diff --git a/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/DestinationIndexSetSection.tsx b/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/DestinationIndexSetSection.tsx index d8de02440665..dfa2bc9621b9 100644 --- a/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/DestinationIndexSetSection.tsx +++ b/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/DestinationIndexSetSection.tsx @@ -19,7 +19,7 @@ import { useState } from 'react'; import styled, { css } from 'styled-components'; import { ARCHIVE_RETENTION_STRATEGY } from 'stores/indices/IndicesStore'; -import { Icon, Section, Spinner, Timestamp } from 'components/common'; +import { Icon, Section, Spinner } from 'components/common'; import { IndexSetsStore, type IndexSet } from 'stores/indices/IndexSetsStore'; import { Table, Button, Alert } from 'components/bootstrap'; import { LinkContainer } from 'components/common/router'; @@ -35,6 +35,9 @@ import DestinationSwitch from 'components/streams/StreamDetails/routing-destinat import SectionCountLabel from 'components/streams/StreamDetails/SectionCountLabel'; import useIndexSetStats from 'hooks/useIndexSetStats'; import { DEFAULT_PAGINATION } from 'stores/PaginationTypes'; +import useIndexerOverview from 'hooks/useIndexerOverview'; + +import IndexSetOldestMessageCell from './IndexSetOldestMessageCell'; type Props = { indexSet: IndexSet, @@ -49,12 +52,13 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => { const [pagination, setPagination] = useState(DEFAULT_PAGINATION); const archivingEnabled = indexSet.retention_strategy_class === ARCHIVE_RETENTION_STRATEGY || indexSet?.data_tiering?.archive_before_deletion; const { indexSets } = useStore(IndexSetsStore); - const { data, isLoading } = useStreamOutputFilters(stream.id, 'indexer', pagination); + const { data: streamOutputFilters, isLoading: isLoadingStreamOutputFilters } = useStreamOutputFilters(stream.id, 'indexer', pagination); + const { data: indexerOverview, isSuccess: isLoadingIndexerOverviewSuccess } = useIndexerOverview(indexSet.id); /* eslint-disable no-constant-condition */ const title = true ? 'Enabled' : 'Disabled'; // TODO use api to check if enabled const { data: indexSetStats, isSuccess: isStatsLoaded } = useIndexSetStats(indexSet.id); - if (isLoading) { + if (isLoadingStreamOutputFilters) { ; } @@ -76,7 +80,7 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => { label={title} disabled onChange={() => {}} /> - FILTERS {data?.pagination?.total || 0} + FILTERS {streamOutputFilters?.pagination?.total || 0} )} actions={( @@ -102,11 +106,10 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => { {indexSet?.title} {(isStatsLoaded && indexSetStats?.size) ? NumberUtils.formatBytes(indexSetStats.size) : 0} - + {isLoadingIndexerOverviewSuccess && } - {} @@ -122,7 +125,7 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => { - {data && ()} + {streamOutputFilters && ()} ); }; diff --git a/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/IndexSetOldestMessageCell.tsx b/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/IndexSetOldestMessageCell.tsx new file mode 100644 index 000000000000..7961c316bc61 --- /dev/null +++ b/graylog2-web-interface/src/components/streams/StreamDetails/routing-destination/IndexSetOldestMessageCell.tsx @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +import * as React from 'react'; + +import { Timestamp } from 'components/common'; +import type { IndexSummary } from 'stores/indexers/IndexerOverviewStore'; + +type Props = { + index?: IndexSummary; +}; + +const IndexSetOldestMessageCell = ({ index = null }: Props) => ( + +); + +export default IndexSetOldestMessageCell; diff --git a/graylog2-web-interface/src/hooks/useIndexerOverview.ts b/graylog2-web-interface/src/hooks/useIndexerOverview.ts new file mode 100644 index 000000000000..8ff1c9015a00 --- /dev/null +++ b/graylog2-web-interface/src/hooks/useIndexerOverview.ts @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +import { useQuery } from '@tanstack/react-query'; + +import UserNotification from 'util/UserNotification'; +import type FetchError from 'logic/errors/FetchError'; +import fetch from 'logic/rest/FetchProvider'; +import { qualifyUrl } from 'util/URLUtils'; +import ApiRoutes from 'routing/ApiRoutes'; +import type { IndexerOverview } from 'stores/indexers/IndexerOverviewStore'; + +const fetchIndexerOverview = (indexSetId: string) => fetch('GET', qualifyUrl(ApiRoutes.IndexerOverviewApiResource.list(indexSetId).url)); + +const useIndexerOverview = (indexSetId: string): { + data: IndexerOverview, + refetch: () => void, + isLoading: boolean, + error: FetchError, + isSuccess: boolean, +} => { + const { data, refetch, isLoading, error, isSuccess } = useQuery( + ['indexerOverview', indexSetId, 'stats'], + () => fetchIndexerOverview(indexSetId), + { + onError: (errorThrown) => { + UserNotification.error(`Loading indexer overview for index set failed with status: ${errorThrown}`, + 'Could not load indexer overview.'); + }, + notifyOnChangeProps: ['data', 'error'], + }, + ); + + return ({ + data, + refetch, + isLoading, + error, + isSuccess, + }); +}; + +export default useIndexerOverview;