From 1df17fa7ee98d7be2d4af1276b208bf226b05c81 Mon Sep 17 00:00:00 2001 From: Linus Pahl Date: Thu, 12 Mar 2026 18:46:26 +0100 Subject: [PATCH] Properly handle search config being loaded. --- .../common/message/details/MessageActions.tsx | 10 +------ .../common/message/details/MessageDetail.tsx | 3 --- .../search/SurroundingSearchButton.tsx | 26 ++++++++++++------- .../src/hooks/useSearchConfiguration.ts | 12 +++++---- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/graylog2-web-interface/src/components/common/message/details/MessageActions.tsx b/graylog2-web-interface/src/components/common/message/details/MessageActions.tsx index 03b6346479..6549540229 100644 --- a/graylog2-web-interface/src/components/common/message/details/MessageActions.tsx +++ b/graylog2-web-interface/src/components/common/message/details/MessageActions.tsx @@ -21,7 +21,6 @@ import { LinkContainer, ClipboardButton } from 'components/common'; import Routes from 'routing/Routes'; import { Button, ButtonGroup, DropdownButton, MenuItem } from 'components/bootstrap'; import SurroundingSearchButton from 'components/search/SurroundingSearchButton'; -import type { SearchesConfig } from 'components/search/SearchConfig'; import usePluginEntities from 'hooks/usePluginEntities'; import { TELEMETRY_EVENT_TYPE } from 'logic/telemetry/Constants'; import useSendTelemetry from 'logic/telemetry/useSendTelemetry'; @@ -92,7 +91,6 @@ type Props = { showOriginal: boolean; toggleShowOriginal: () => void; streams: Immutable.List; - searchConfig: SearchesConfig; }; const MessageActions = ({ @@ -106,7 +104,6 @@ const MessageActions = ({ showOriginal, toggleShowOriginal, streams, - searchConfig, }: Props) => { const pluggableActions = usePluggableMessageActions(id, index); const isFavoriteFieldsEnabled = useFeature('message_table_favorite_fields'); @@ -118,12 +115,7 @@ const MessageActions = ({ const { timestamp, ...remainingFields } = fields; const surroundingSearchButton = disableSurroundingSearch || ( - + ); const showChanges = decorationStats && ( diff --git a/graylog2-web-interface/src/components/common/message/details/MessageDetail.tsx b/graylog2-web-interface/src/components/common/message/details/MessageDetail.tsx index 7ecfc513d2..195edbf541 100644 --- a/graylog2-web-interface/src/components/common/message/details/MessageDetail.tsx +++ b/graylog2-web-interface/src/components/common/message/details/MessageDetail.tsx @@ -32,7 +32,6 @@ import type { Stream } from 'views/stores/StreamsStore'; import type { FieldTypeMappingsList } from 'views/logic/fieldtypes/types'; import useIsLocalNode from 'views/hooks/useIsLocalNode'; import FieldTypesContext from 'views/components/contexts/FieldTypesContext'; -import useSearchConfiguration from 'hooks/useSearchConfiguration'; import useFeature from 'hooks/useFeature'; import MessageFavoriteFieldsProvider from './context/MessageFavoriteFieldsProvider'; @@ -91,7 +90,6 @@ const MessageDetail = ({ allStreams = Immutable.List(), }: Props) => { const isFavoriteFieldsEnabled = useFeature('message_table_favorite_fields'); - const { config: searchesClusterConfig } = useSearchConfiguration(); const [showOriginal, setShowOriginal] = useState(false); const { fields, index, id, decoration_stats: decorationStats } = message; const { gl2_source_node, gl2_source_input, associated_assets } = fields; @@ -162,7 +160,6 @@ const MessageDetail = ({ disableTestAgainstStream={disableTestAgainstStream} showOriginal={showOriginal} toggleShowOriginal={_toggleShowOriginal} - searchConfig={searchesClusterConfig} streams={allStreams} /> diff --git a/graylog2-web-interface/src/components/search/SurroundingSearchButton.tsx b/graylog2-web-interface/src/components/search/SurroundingSearchButton.tsx index 598d6a6088..e0b0fb6889 100644 --- a/graylog2-web-interface/src/components/search/SurroundingSearchButton.tsx +++ b/graylog2-web-interface/src/components/search/SurroundingSearchButton.tsx @@ -26,23 +26,25 @@ import { TELEMETRY_EVENT_TYPE } from 'logic/telemetry/Constants'; import useSendTelemetry from 'logic/telemetry/useSendTelemetry'; import { getPathnameWithoutId } from 'util/URLUtils'; import useLocation from 'routing/useLocation'; +import useSearchConfiguration from 'hooks/useSearchConfiguration'; import type { SearchesConfig } from './SearchConfig'; -const buildTimeRangeOptions = ({ - surrounding_timerange_options: surroundingTimerangeOptions = {}, -}: Pick) => - Object.fromEntries( +const buildTimeRangeOptions = (searchConfig: Pick | undefined) => { + const surroundingTimerangeOptions = searchConfig?.surrounding_timerange_options ?? {}; + + return Object.fromEntries( Object.entries(surroundingTimerangeOptions).map(([key, value]) => [moment.duration(key).asSeconds(), value]), ); +}; const buildFilterFields = ( messageFields: { [x: string]: unknown; }, - searchConfig: Pick, + searchConfig: Pick | undefined, ) => { - const { surrounding_filter_fields: surroundingFilterFields = [] } = searchConfig; + const surroundingFilterFields = searchConfig?.surrounding_filter_fields ?? []; return Object.fromEntries(surroundingFilterFields.map((fieldName) => [fieldName, messageFields[fieldName]])); }; @@ -73,7 +75,7 @@ const searchLink = ( messageFields: { [key: string]: unknown; }, - searchConfig: Pick, + searchConfig: Pick | undefined, streams: string[], streamCategories: string[], ) => { @@ -85,14 +87,14 @@ const searchLink = ( }; type Props = { - searchConfig: Pick; timestamp: string; id: string; messageFields: { [key: string]: unknown }; }; -const SurroundingSearchButton = ({ searchConfig, timestamp, id, messageFields }: Props) => { +const SurroundingSearchButton = ({ timestamp, id, messageFields }: Props) => { const { streams, streamCategories } = useContext(DrilldownContext); + const { config: searchConfig, isInitialLoading: isLoadingSearchConfig } = useSearchConfiguration(); const timeRangeOptions = buildTimeRangeOptions(searchConfig); const location = useLocation(); const sendTelemetry = useSendTelemetry(); @@ -122,7 +124,11 @@ const SurroundingSearchButton = ({ searchConfig, timestamp, id, messageFields }: )); return ( - + {menuItems} ); diff --git a/graylog2-web-interface/src/hooks/useSearchConfiguration.ts b/graylog2-web-interface/src/hooks/useSearchConfiguration.ts index 2e15382330..26be2b8f00 100644 --- a/graylog2-web-interface/src/hooks/useSearchConfiguration.ts +++ b/graylog2-web-interface/src/hooks/useSearchConfiguration.ts @@ -17,14 +17,16 @@ import type { SearchesConfig } from 'components/search/SearchConfig'; import useClusterConfig from 'hooks/useClusterConfig'; -type Result = { config: SearchesConfig; refresh: () => void }; +type Result = { config: SearchesConfig | undefined; refresh: () => void; isInitialLoading: boolean }; const useSearchConfiguration = (): Result => { - const { data: config, refetch } = useClusterConfig( - 'org.graylog2.indexer.searches.SearchesClusterConfig', - ); + const { + data: config, + refetch, + isInitialLoading, + } = useClusterConfig('org.graylog2.indexer.searches.SearchesClusterConfig'); - return { config, refresh: refetch }; + return { config, refresh: refetch, isInitialLoading }; }; export default useSearchConfiguration;