diff --git a/x-pack/plugins/dataset_quality/common/translations.ts b/x-pack/plugins/dataset_quality/common/translations.ts index 43752f324fcca..a049dc67a1b9a 100644 --- a/x-pack/plugins/dataset_quality/common/translations.ts +++ b/x-pack/plugins/dataset_quality/common/translations.ts @@ -83,3 +83,26 @@ export const flyoutIntegrationNameText = i18n.translate( defaultMessage: 'Name', } ); + +export const inactiveDatasetsLabel = i18n.translate('xpack.datasetQuality.inactiveDatasetsLabel', { + defaultMessage: 'Show inactive datasets', +}); + +export const inactiveDatasetsDescription = i18n.translate( + 'xpack.datasetQuality.inactiveDatasetsDescription', + { + defaultMessage: + 'Turn on to show datasets with a Last activity outside of the selected timeframe.', + } +); + +export const fullDatasetNameLabel = i18n.translate('xpack.datasetQuality.fullDatasetNameLabel', { + defaultMessage: 'Show full dataset names', +}); + +export const fullDatasetNameDescription = i18n.translate( + 'xpack.datasetQuality.fullDatasetNameDescription', + { + defaultMessage: 'Turn on to show the actual dataset names used to store the documents.', + } +); diff --git a/x-pack/plugins/dataset_quality/public/components/common/descriptive_switch.tsx b/x-pack/plugins/dataset_quality/public/components/common/descriptive_switch.tsx new file mode 100644 index 0000000000000..a7db9596b8534 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/common/descriptive_switch.tsx @@ -0,0 +1,35 @@ +/* + * 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. + */ + +import { EuiFlexGroup, EuiIcon, EuiSwitch, EuiText, EuiToolTip } from '@elastic/eui'; +import React from 'react'; + +interface DescriptiveSwitchProps { + label: string; + checked: boolean; + tooltipText: string; + onToggle: () => void; +} + +export const DescriptiveSwitch = ({ + label, + checked, + tooltipText, + onToggle, +}: DescriptiveSwitchProps) => { + return ( + + + + {label} + + + + + + ); +}; diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx index fe50c291f9fcf..00afbb76bd8f8 100644 --- a/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx @@ -63,10 +63,25 @@ const lastActivityColumnName = i18n.translate('xpack.datasetQuality.lastActivity const actionsColumnName = i18n.translate('xpack.datasetQuality.actionsColumnName', { defaultMessage: 'Actions', }); + const openActionName = i18n.translate('xpack.datasetQuality.openActionName', { defaultMessage: 'Open', }); +const inactiveDatasetActivityColumnDescription = i18n.translate( + 'xpack.datasetQuality.inactiveDatasetActivityColumnDescription', + { + defaultMessage: 'No activity in the selected timeframe', + } +); + +const inactiveDatasetActivityColumnTooltip = i18n.translate( + 'xpack.datasetQuality.inactiveDatasetActivityColumnTooltip', + { + defaultMessage: 'Try expanding the time range above for more results', + } +); + const degradedDocsDescription = (minimimPercentage: number) => i18n.translate('xpack.datasetQuality.degradedDocsQualityDescription', { defaultMessage: 'greater than {minimimPercentage}%', @@ -111,11 +126,15 @@ export const getDatasetQualityTableColumns = ({ selectedDataset, openFlyout, loadingDegradedStats, + showFullDatasetNames, + isActiveDataset, }: { fieldFormats: FieldFormatsStart; selectedDataset?: FlyoutDataset; - loadingDegradedStats?: boolean; + loadingDegradedStats: boolean; + showFullDatasetNames: boolean; openFlyout: (selectedDataset: FlyoutDataset) => void; + isActiveDataset: (lastActivity: number) => boolean; }): Array> => { return [ { @@ -146,7 +165,7 @@ export const getDatasetQualityTableColumns = ({ field: 'title', sortable: true, render: (title: string, dataStreamStat: DataStreamStat) => { - const { integration } = dataStreamStat; + const { integration, name } = dataStreamStat; return ( @@ -154,6 +173,11 @@ export const getDatasetQualityTableColumns = ({ {title} + {showFullDatasetNames && ( + + {name} + + )} ); }, @@ -199,10 +223,22 @@ export const getDatasetQualityTableColumns = ({ { name: lastActivityColumnName, field: 'lastActivity', - render: (timestamp: number) => - fieldFormats + render: (timestamp: number) => { + if (!isActiveDataset(timestamp)) { + return ( + + {inactiveDatasetActivityColumnDescription} + + + + + ); + } + + return fieldFormats .getDefaultInstance(KBN_FIELD_TYPES.DATE, [ES_FIELD_TYPES.DATE]) - .convert(timestamp), + .convert(timestamp); + }, sortable: true, }, { diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx index 4779453a14d6c..cd4991ee08915 100644 --- a/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx @@ -5,12 +5,27 @@ * 2.0. */ -import React from 'react'; -import { EuiBasicTable, EuiHorizontalRule, EuiSpacer, EuiText, EuiEmptyPrompt } from '@elastic/eui'; +import { + EuiBasicTable, + EuiEmptyPrompt, + EuiFlexGroup, + EuiHorizontalRule, + EuiSpacer, + EuiText, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { dynamic } from '@kbn/shared-ux-utility'; -import { loadingDatasetsText, noDatasetsTitle } from '../../../common/translations'; +import React from 'react'; +import { + fullDatasetNameDescription, + fullDatasetNameLabel, + inactiveDatasetsDescription, + inactiveDatasetsLabel, + loadingDatasetsText, + noDatasetsTitle, +} from '../../../common/translations'; import { useDatasetQualityTable } from '../../hooks'; +import { DescriptiveSwitch } from '../common/descriptive_switch'; const Flyout = dynamic(() => import('../flyout/flyout')); @@ -25,19 +40,39 @@ export const Table = () => { resultsCount, selectedDataset, closeFlyout, + showInactiveDatasets, + showFullDatasetNames, + toggleInactiveDatasets, + toggleFullDatasetNames, } = useDatasetQualityTable(); return ( <> - - - + + + + + + + + + ; service: DatasetQualityControllerStateService; } -export interface DatasetQualityTableOptions { - page?: number; - rowsPerPage?: number; - sort?: { - field: string; - direction: Direction; - }; -} +type TableSortOptions = Omit & { field: string }; -type FlyoutOptions = Omit< - DataStreamStat, - 'type' | 'size' | 'sizeBytes' | 'lastActivity' | 'degradedDocs' +export type DatasetQualityTableOptions = Partial< + Omit & { sort: TableSortOptions } >; -export interface DatasetQualityFlyoutOptions { - dataset?: FlyoutOptions & { type: string }; -} +export type DatasetQualityFlyoutOptions = Omit; + +export type DatasetQualityFilterOptions = Partial>; export interface DatasetQualityPublicState { table: DatasetQualityTableOptions; flyout: DatasetQualityFlyoutOptions; + filters: DatasetQualityFilterOptions; } export type DatasetQualityPublicStateUpdate = Partial; diff --git a/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx b/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx index 96f383f810b1b..bffa271ed9159 100644 --- a/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx +++ b/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx @@ -15,6 +15,7 @@ import { getDatasetQualityTableColumns } from '../components/dataset_quality/col import { useDatasetQualityContext } from '../components/dataset_quality/context'; import { FlyoutDataset } from '../state_machines/dataset_quality_controller'; import { useKibanaContextForPlugin } from '../utils'; +import { filterInactiveDatasets, isActiveDataset } from '../utils/filter_inactive_datasets'; export type Direction = 'asc' | 'desc'; export type SortField = keyof DataStreamStat; @@ -33,6 +34,12 @@ export const useDatasetQualityTable = () => { const { page, rowsPerPage, sort } = useSelector(service, (state) => state.context.table); + const { + inactive: showInactiveDatasets, + fullNames: showFullDatasetNames, + timeRange, + } = useSelector(service, (state) => state.context.filters); + const flyout = useSelector(service, (state) => state.context.flyout); const loading = useSelector(service, (state) => state.matches('datasets.fetching')); @@ -46,6 +53,16 @@ export const useDatasetQualityTable = () => { state.matches('datasets.loaded.idle') ); + const toggleInactiveDatasets = useCallback( + () => service.send({ type: 'TOGGLE_INACTIVE_DATASETS' }), + [service] + ); + + const toggleFullDatasetNames = useCallback( + () => service.send({ type: 'TOGGLE_FULL_DATASET_NAMES' }), + [service] + ); + const closeFlyout = useCallback(() => service.send({ type: 'CLOSE_FLYOUT' }), [service]); const openFlyout = useCallback( (selectedDataset: FlyoutDataset) => { @@ -73,6 +90,11 @@ export const useDatasetQualityTable = () => { [flyout?.dataset?.rawName, isDatasetQualityPageIdle, service] ); + const isActive = useCallback( + (lastActivity: number) => isActiveDataset({ lastActivity, timeRange }), + [timeRange] + ); + const columns = useMemo( () => getDatasetQualityTableColumns({ @@ -80,14 +102,28 @@ export const useDatasetQualityTable = () => { selectedDataset: flyout?.dataset, openFlyout, loadingDegradedStats, + showFullDatasetNames, + isActiveDataset: isActive, }), - [flyout?.dataset, fieldFormats, loadingDegradedStats, openFlyout] + [ + fieldFormats, + flyout?.dataset, + openFlyout, + loadingDegradedStats, + showFullDatasetNames, + isActive, + ] + ); + + const filteredItems = useMemo( + () => (showInactiveDatasets ? datasets : filterInactiveDatasets({ datasets, timeRange })), + [showInactiveDatasets, datasets, timeRange] ); const pagination = { pageIndex: page, pageSize: rowsPerPage, - totalItemCount: datasets.length, + totalItemCount: filteredItems.length, hidePerPageOptions: true, }; @@ -113,13 +149,13 @@ export const useDatasetQualityTable = () => { const renderedItems = useMemo(() => { const overridenSortingField = sortingOverrides[sort.field] || sort.field; - const sortedItems = orderBy(datasets, overridenSortingField, sort.direction); + const sortedItems = orderBy(filteredItems, overridenSortingField, sort.direction); return sortedItems.slice(page * rowsPerPage, (page + 1) * rowsPerPage); - }, [sort.field, sort.direction, datasets, page, rowsPerPage]); + }, [sort.field, sort.direction, filteredItems, page, rowsPerPage]); const resultsCount = useMemo(() => { - const startNumberItemsOnPage = rowsPerPage ?? 1 * page ?? 0 + (renderedItems.length ? 1 : 0); + const startNumberItemsOnPage = rowsPerPage * page + 1; const endNumberItemsOnPage = rowsPerPage * page + renderedItems.length; return rowsPerPage === 0 ? ( @@ -144,5 +180,9 @@ export const useDatasetQualityTable = () => { resultsCount, closeFlyout, selectedDataset: flyout?.dataset, + showInactiveDatasets, + showFullDatasetNames, + toggleInactiveDatasets, + toggleFullDatasetNames, }; }; diff --git a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts index ecd044727f610..64bea002b4472 100644 --- a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts +++ b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getDefaultTimeRange } from '../../../utils'; import { DEFAULT_SORT_DIRECTION, DEFAULT_SORT_FIELD } from '../../../../common/constants'; import { DefaultDatasetQualityControllerState } from './types'; @@ -17,6 +18,11 @@ export const DEFAULT_CONTEXT: DefaultDatasetQualityControllerState = { direction: DEFAULT_SORT_DIRECTION, }, }, + filters: { + inactive: true, + fullNames: false, + timeRange: getDefaultTimeRange(), + }, flyout: {}, datasets: [], }; diff --git a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts index b2222ea3c0d02..8c8f66a008677 100644 --- a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts +++ b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts @@ -12,7 +12,6 @@ import { DataStreamDetails } from '../../../../common/data_streams_stats'; import { DataStreamType } from '../../../../common/types'; import { dataStreamPartsToIndexName } from '../../../../common/utils'; import { DataStreamStat } from '../../../../common/data_streams_stats/data_stream_stat'; -import { getDefaultTimeRange } from '../../../utils'; import { IDataStreamsStatsClient } from '../../../services/data_streams_stats'; import { DEFAULT_CONTEXT } from './defaults'; import { @@ -32,7 +31,7 @@ import { export const createPureDatasetQualityControllerStateMachine = ( initialContext: DatasetQualityControllerContext ) => - /** @xstate-layout N4IgpgJg5mDOIC5QBECGAXVszoIoFdUAbAS3QE8BhAewDt0AnaoosBgOggyx1nYDMcAYwAWJWlADEEOmHbiAbtQDWctJmx5CpCjXpMWbTt019B6UeKgJF1IRhJ0A2gAYAuq7eJQAB2qwyR1pvEAAPRABaADYAVnYADgBORIBGABZUtIBmLPiUgCY0gBoQckj8xPZ8lJi0lPiXKKi0-KyXeLSAX06S9R4tYjIqOkZmVg4uDV4BYTEJSTYmDh8iDH5qBgBbdj7NAkHdEYNx4yn0M1mrG1ole3Qgz08QvwD7uhDwhGSAdnYYlMSMXiMXy31iUWBJTKCAiNXY3xiURcaTSLhSLm+aW+yUS3V6Jhw+x0w30YyMk36fCI1FQEEgkgAqgAFZAAQQAKgBRAD67NZACEADI8ygAJQAklyJaynkgQC9Au85Z8QfF2C1WqksmDvoV8lDIgDfvF4lFvjVWkkIfEsniQLtCdohnpRoYJmAoAxaZBkHYLhY5lIZLQ5LZVDsCQNiS7juSPV66RBfUJ-ZYJNdbg5nO5Zb5-IrgsrEOj8nFvmj2vl8i4ay59aVEK18n9vib2jWoolvrlvnaHVHnUcye7Pd6k36ZgGrAsGEt2Cs1httv2iYPSW7OPGx8nU4GM3Ys7RHu5nvm3oXQJ8Irr2C5Ema2siWlEsqCDQhClFb7lq6iYveXxNPtI1XQ51xOfgiHIah8HQSQAGVOWFSh2W5AA5TkAHVuTZPlEPZXN5TPIIPkQNIGgSRIshqZpTRcHJigbBBETVeJdTqZpzUA+JgLOUCSVdCCoJguDKEFAB5RDuQAMUFABNcSGQIk85QVc9SJhbsqiiaoCiyFEOl098mkqRp4mrJIUiabtex6e0QKdMDBKMSDoNgyc0yDWR5BuFQ1Acg4BNjDhXJEjy91sO4HhzFS81eEiiwQG1KmxOiXBibVGkSeJ311ZsITSGIYnS2IawyXj+n4mNhwEYT3PMTyZznBd0HWLYIz4xygpq0L6sudNIsPY8vFU4ilUvRA8hSW8WkBU0qIBdp3yBSpgXLcsmnaRJyrslcuuqjdevQdhqTHSQxMknlZIUpTCLUhKJo-WJ4VNVsUlfF9snyKJ3zWv42MK5JURffIKr2fah0OurjqEalsAgSRxKZTk0Jk+TFOUka4oLDTQWm9KCnRO9iuqH6mM7L8wTycs0U7ZJbTtWhqDpeA5T2wKDvGU94vGsJDU7bTdNaAyWhSd8Im1fKUgRb5dRrbKslxXaAujSGTgpUxuZxxLYXeyjMkyHI8kKcX8mBKoQRqSyzSieowcdDm1fJSNdysLX1MSkE0nYLtEjNztajSWJ62hCJWL0tikiK4q2PtgcnOC05KROmlE3dh6+YQcjm1bJEzYRdo8kScWu3YaiwWo+pOPaOOqqdkcEx9P1095q8ChcW9727Mrn1fb533SOJqhyZpX1SBolfxTrHfAuNR0THdwrd0aeYvTOg+9rFqkBQp6JyfumMKLJ4TaaXQSRGXGlriHZ4b7cJ1OtOV+1x7A4SNobVbIEaJDxBtUqb6LQkg2gqI0BmU9Ko32ciFaGLc15t2qILFIekRZGSYuRaaxVyzVGRFZNoXRlbT1VrfWqbljoNUDHAjSWIvwFEBmbLInFZYxGMoCH2n1qxVgBBPa+M9oGkLCo-SAVDErIPIuqcyvs6xsVLGTaE3Zppf3-M0LsR9bIQPBnwxOR12Cw38MI5+HtHrpF+JxEmFRpZvRYUxc0lRFZ1G1HUdEKRujdCAA */ + /** @xstate-layout N4IgpgJg5mDOIC5QBECGAXVszoIoFdUAbAS3QE8BhAewDt0AnaoosBgOggyx1nYDMcAYwAWJWlADEEOmHbiAbtQDWctJmx5CpCjXpMWbTt019B6UeKgJF1IRhJ0A2gAYAuq7eJQAB2qwyR1pvEAAPRAAWADYARnYATgBmAHYo+OSADniYlwBWGIAaEHJEZIAmDPYI+JcImJissuSXDIiAXzai9R4tYjIqOkZmVg4uDV4BYTEJSTYmDh8iDH5qBgBbdm7NAj7dQYMR43H0MymrG1ole3Qgz08QvwCbuhDwhCjKiNqY3OTE9LKEWqZSKJQQ5Vy7GS0Xq8Si0KBETKHS6JhwOx0A30wyMYx6fCI1FQEEgkgAqgAFZAAQQAKgBRAD6tOpACEADJMygAJQAkgy+dT7kgQI9Ai8RW9ctl2IkYpkMnL4oqIolQYgcnkEmVclEorkXPEykb4SiQFt0dp+nohoZRmiTuxCcTSbSAPIAcQ9nMZvIActTKLTeQA1Jk0lkAZXptMjwt8-nFwUliDSyXYaUSZUNSWVLnK6oQGRa7DKctyBuVcpciSiZotvUxNoOuIdBKJJIgkndXp9ADEyez2YyI9To7TGQGALL0uPuB6J57J0BvbOVeFRMvy3IRHcufWFzWQo26-WG41lPX1h0Y637HGjMBQBguiDIOynCzTKQyWhyWyqJsN5Wns2J2pwT4vp275CJ+lgSBcVwOM47jxqKi5BK8pQZJCyQxNmubpBEyTpIeTRxBkZQ6k0NapHWnTmsBuxYrahwks+r4wXB36zAw8zsIsyyrBsDa3qBrG4pBnEfpMX7nLY1y3Kh84imKS5Ye8UTsDEqrlC4LiAlkMTxPEZE4aWGTGS0yQ2Yk+7XscYksS2HD8EQ5DUPg6CSNGnJBpO9IAOojnSY4xmhamYSm4JxFRHzKmUOTRCkpnFIg-yQrq0TxF8dQxGkDk9E5zYPgI7med5lDsm60aMn27IAJpumStIRRhEorqUsWXlklFJVEKWHjpspVoqOVGkaeGFdsIHOaVbkeV5snwT+sjyJcKhqExTb3uBC0Vct36IXYyG0HcKkJk8UWdUWrTsAa8KpJZ+U2alYKJNE2q5JRmR1FE+aJNNlrMSVe3lUt5grbx-GCegKzrEBjmzaDhz7RDZwIQpp3nV4qntcuYSIBkfwZtCMQpNmOT-IWiVaYlLj5RkA2Klk9kMaJyO7aj4PoE6HaklVNVMvVTUtW1V0dYTCDxN991ZNCgJGsTTSHiWlkVv8Ro-ArMRA42d5gdzi280IhLYF2boUvSfp1Y1zWtRd6ESwTbx1BE7DFtKOUpLW+nkzTuRlNpNQ6fhm6ZKaZq0NQJLwCKHMg1zbALs7GkALTGh7upNCZyT5C0DOFmn+oJD8FRjTL-2UXrxVJ-axxx5dSYadmVTfL8-zlEC2RRIWuSJMeEStIl+S6j8Nec4brYN4dVgp830U0VCHw2fUSW9YWm6JLK5MqtWu7Iuz20GxJ9f4nzr7z+p0X5PE2kkfC+EU4ahbZOmdlexlaQyxPidT4+HFoIfivtdKWDRtK6WzAZIe2QTJDXyKWJIuo8KAmaDlX+O1-4QUAZALis8JAgMlq7LUNYZb4SyP3HCEQyKJHXN9dIJljI7gGhgk+LlsFQVwTJZ0nZCEu0iBkSoOp9TdzsruBmvc0oIHJlEd2WtoRoKpkPVh4l2Fo3QHwlu284q9XpslTIyQaZxHEfhVUMsmj-RYUfJGf9T5lWNvgqAmjor-UhLUL4hpfjFmIrkGmeoEi7nqHheoA0NwqLmmDBxPDIDOJuvUIeWdqgM1SB9SiNNMgZmqP8Sy+oPj6nCSjIw6j2Cm38DEvGqdop2XTDuOoJEXqqgHoeFI91AQDyrozJIh8OhAA */ createMachine< DatasetQualityControllerContext, DatasetQualityControllerEvent, @@ -66,6 +65,14 @@ export const createPureDatasetQualityControllerStateMachine = ( target: 'loaded', actions: ['storeTableOptions'], }, + TOGGLE_INACTIVE_DATASETS: { + target: 'loaded', + actions: ['storeInactiveDatasetsVisibility', 'resetPage'], + }, + TOGGLE_FULL_DATASET_NAMES: { + target: 'loaded', + actions: ['storeFullDatasetNamesVisibility'], + }, }, }, }, @@ -144,6 +151,28 @@ export const createPureDatasetQualityControllerStateMachine = ( } : {}; }), + resetPage: assign((context, _event) => ({ + table: { + ...context.table, + page: 0, + }, + })), + storeInactiveDatasetsVisibility: assign((context, _event) => { + return { + filters: { + ...context.filters, + inactive: !context.filters.inactive, + }, + }; + }), + storeFullDatasetNamesVisibility: assign((context, _event) => { + return { + filters: { + ...context.filters, + fullNames: !context.filters.fullNames, + }, + }; + }), storeFlyoutOptions: assign((context, event) => { return 'dataset' in event ? { @@ -217,14 +246,11 @@ export const createDatasetQualityControllerStateMachine = ({ }, services: { loadDataStreamStats: (_context) => dataStreamStatsClient.getDataStreamsStats(), - loadDegradedDocs: (_context) => { - const defaultTimeRange = getDefaultTimeRange(); - - return dataStreamStatsClient.getDataStreamsDegradedStats({ - start: defaultTimeRange.from, - end: defaultTimeRange.to, - }); - }, + loadDegradedDocs: (context) => + dataStreamStatsClient.getDataStreamsDegradedStats({ + start: context.filters.timeRange.from, + end: context.filters.timeRange.to, + }), loadDataStreamDetails: (context) => { if (!context.flyout.dataset) { fetchDatasetDetailsFailedNotifier(toasts, new Error(noDatasetSelected)); diff --git a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts index 4e059bd9dbeaa..bde8ca84a06e8 100644 --- a/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts +++ b/x-pack/plugins/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts @@ -15,18 +15,10 @@ import { } from '../../../../common/data_streams_stats'; import { DataStreamStat } from '../../../../common/data_streams_stats/data_stream_stat'; -export interface FlyoutDataset { - rawName: string; - type: string; - name: string; - namespace: string; - title: string; - integration?: { - name: string; - title: string; - version: string; - }; -} +export type FlyoutDataset = Omit< + DataStreamStat, + 'type' | 'size' | 'sizeBytes' | 'lastActivity' | 'degradedDocs' +> & { type: string }; interface TableCriteria { page: number; @@ -37,6 +29,15 @@ interface TableCriteria { }; } +interface FiltersCriteria { + inactive: boolean; + fullNames: boolean; + timeRange: { + from: string; + to: string; + }; +} + export interface WithTableOptions { table: TableCriteria; } @@ -48,6 +49,10 @@ export interface WithFlyoutOptions { }; } +export interface WithFilters { + filters: FiltersCriteria; +} + export interface WithDataStreamStats { dataStreamStats: DataStreamStat[]; } @@ -64,7 +69,8 @@ export type DefaultDatasetQualityControllerState = WithTableOptions & Partial & Partial & WithFlyoutOptions & - WithDatasets; + WithDatasets & + WithFilters; type DefaultDatasetQualityStateContext = DefaultDatasetQualityControllerState & Partial; @@ -117,6 +123,12 @@ export type DatasetQualityControllerEvent = | { type: 'CLOSE_FLYOUT'; } + | { + type: 'TOGGLE_INACTIVE_DATASETS'; + } + | { + type: 'TOGGLE_FULL_DATASET_NAMES'; + } | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent; diff --git a/x-pack/plugins/dataset_quality/public/utils/filter_inactive_datasets.ts b/x-pack/plugins/dataset_quality/public/utils/filter_inactive_datasets.ts new file mode 100644 index 0000000000000..c741e5a7b9f09 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/utils/filter_inactive_datasets.ts @@ -0,0 +1,53 @@ +/* + * 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. + */ + +import { DataStreamStat } from '../../common/data_streams_stats'; + +interface FilterInactiveDatasetsOptions { + datasets: DataStreamStat[]; + timeRange: { + from: string; + to: string; + }; +} + +export const filterInactiveDatasets = (options: FilterInactiveDatasetsOptions) => { + const { + datasets, + timeRange: { from, to }, + } = options; + + const startDate = new Date(from).getTime(); + const endDate = new Date(to).getTime(); + + return datasets.filter((dataset) => + dataset.lastActivity ? isActive(dataset.lastActivity, startDate, endDate) : false + ); +}; + +interface IsActiveDatasetOptions { + lastActivity: number; + timeRange: { + from: string; + to: string; + }; +} + +export const isActiveDataset = (options: IsActiveDatasetOptions) => { + const { + lastActivity, + timeRange: { from, to }, + } = options; + + const startDate = new Date(from).getTime(); + const endDate = new Date(to).getTime(); + + return isActive(lastActivity, startDate, endDate); +}; + +const isActive = (lastActivity: number, startDate: number, endDate: number) => + lastActivity >= startDate && lastActivity <= endDate; diff --git a/x-pack/plugins/dataset_quality/public/utils/merge_degraded_docs_into_datastreams.ts b/x-pack/plugins/dataset_quality/public/utils/merge_degraded_docs_into_datastreams.ts index e51309f413647..7ca06f5471895 100644 --- a/x-pack/plugins/dataset_quality/public/utils/merge_degraded_docs_into_datastreams.ts +++ b/x-pack/plugins/dataset_quality/public/utils/merge_degraded_docs_into_datastreams.ts @@ -21,6 +21,6 @@ export function mergeDegradedStatsIntoDataStreams( return dataStreamStats?.map((dataStream) => ({ ...dataStream, - degradedDocs: degradedMap[dataStream.name], + degradedDocs: degradedMap[dataStream.rawName], })); } diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/dataset_quality/url_schema_v1.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/dataset_quality/url_schema_v1.ts index f8afdec14f23a..8633bb160bde5 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/dataset_quality/url_schema_v1.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/dataset_quality/url_schema_v1.ts @@ -52,11 +52,19 @@ export const flyoutRT = rt.exact( }) ); +export const filtersRT = rt.exact( + rt.partial({ + inactive: rt.boolean, + fullNames: rt.boolean, + }) +); + export const urlSchemaRT = rt.exact( rt.partial({ v: rt.literal(1), table: tableRT, flyout: flyoutRT, + filters: filtersRT, }) ); diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/dataset_quality/src/url_schema_v1.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/dataset_quality/src/url_schema_v1.ts index 07ec20798b5c2..512219c9b0099 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/dataset_quality/src/url_schema_v1.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/dataset_quality/src/url_schema_v1.ts @@ -15,6 +15,7 @@ export const getStateFromUrlValue = ( deepCompactObject({ table: urlValue.table, flyout: urlValue.flyout, + filters: urlValue.filters, }); export const getUrlValueFromState = ( @@ -23,6 +24,7 @@ export const getUrlValueFromState = ( deepCompactObject({ table: state.table, flyout: state.flyout, + filters: state.filters, v: 1, });