Properly handle search config being loaded.

This commit is contained in:
Linus Pahl
2026-03-12 18:46:26 +01:00
parent e4ed322a00
commit 1df17fa7ee
4 changed files with 24 additions and 27 deletions

View File

@@ -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<any>;
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 || (
<SurroundingSearchButton
id={id}
timestamp={timestamp as string}
searchConfig={searchConfig}
messageFields={remainingFields}
/>
<SurroundingSearchButton id={id} timestamp={timestamp as string} messageFields={remainingFields} />
);
const showChanges = decorationStats && (

View File

@@ -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}
/>
</Header>

View File

@@ -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<SearchesConfig, 'surrounding_timerange_options'>) =>
Object.fromEntries(
const buildTimeRangeOptions = (searchConfig: Pick<SearchesConfig, 'surrounding_timerange_options'> | 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<SearchesConfig, 'surrounding_filter_fields'>,
searchConfig: Pick<SearchesConfig, 'surrounding_filter_fields'> | 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<SearchesConfig, 'surrounding_filter_fields'>,
searchConfig: Pick<SearchesConfig, 'surrounding_filter_fields'> | undefined,
streams: string[],
streamCategories: string[],
) => {
@@ -85,14 +87,14 @@ const searchLink = (
};
type Props = {
searchConfig: Pick<SearchesConfig, 'surrounding_timerange_options' | 'surrounding_filter_fields'>;
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 (
<DropdownButton title="Show surrounding messages" bsSize="small" id="surrounding-search-dropdown">
<DropdownButton
title="Show surrounding messages"
bsSize="small"
id="surrounding-search-dropdown"
disabled={isLoadingSearchConfig}>
{menuItems}
</DropdownButton>
);

View File

@@ -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<SearchesConfig>(
'org.graylog2.indexer.searches.SearchesClusterConfig',
);
const {
data: config,
refetch,
isInitialLoading,
} = useClusterConfig<SearchesConfig>('org.graylog2.indexer.searches.SearchesClusterConfig');
return { config, refresh: refetch };
return { config, refresh: refetch, isInitialLoading };
};
export default useSearchConfiguration;