in src/platform/plugins/shared/unified_search/public/query_string_input/query_bar_menu_panels.tsx [193:608]
export function useQueryBarMenuPanels({
filters,
additionalQueryBarMenuItems,
savedQuery,
language,
dateRangeFrom,
dateRangeTo,
timeFilter,
query,
showSaveQuery,
showSavedQueryControls = true,
showFilterBar,
showQueryInput,
savedQueryService,
saveFormComponent,
saveAsNewQueryFormComponent,
manageFilterSetComponent,
hiddenPanelOptions,
nonKqlMode,
disableQueryLanguageSwitcher = false,
queryBarMenuRef,
closePopover,
onQueryBarSubmit,
onFiltersUpdated,
onClearSavedQuery,
onQueryChange,
setRenderedComponent,
}: QueryBarMenuPanelsProps) {
const kibana = useKibana<IUnifiedSearchPluginServices>();
const { appName, usageCollection, uiSettings, http, storage, application } = kibana.services;
const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName);
const showSavedQueries =
showSavedQueryControls &&
showQueryInput &&
showFilterBar &&
application.capabilities.savedQueryManagement?.showQueries;
const cancelPendingListingRequest = useRef<() => void>(() => {});
const [hasSavedQueries, setHasSavedQueries] = useState(false);
const [hasFiltersOrQuery, setHasFiltersOrQuery] = useState(false);
const [savedQueryHasChanged, setSavedQueryHasChanged] = useState(false);
useEffect(() => {
if (savedQuery) {
cancelPendingListingRequest.current();
setHasSavedQueries(true);
}
}, [savedQuery]);
useEffect(() => {
const fetchSavedQueries = async () => {
cancelPendingListingRequest.current();
let requestGotCancelled = false;
cancelPendingListingRequest.current = () => {
requestGotCancelled = true;
};
const queryCount = await savedQueryService.getSavedQueryCount();
if (requestGotCancelled) return;
setHasSavedQueries(queryCount > 0);
};
if (showSavedQueries) {
fetchSavedQueries();
}
}, [savedQueryService, showSavedQueries]);
useEffect(() => {
if (savedQuery) {
const filtersHaveChanged = Boolean(
savedQuery?.attributes.filters &&
!compareFilters(filters ?? [], savedQuery.attributes.filters, COMPARE_ALL_OPTIONS)
);
const timeFilterHasChanged = Boolean(
savedQuery?.attributes.timefilter && !isEqual(timeFilter, savedQuery?.attributes.timefilter)
);
if (
filtersHaveChanged ||
timeFilterHasChanged ||
!isEqual(query, savedQuery?.attributes.query)
) {
setSavedQueryHasChanged(true);
} else {
setSavedQueryHasChanged(false);
}
}
}, [filters, query, savedQuery, timeFilter]);
useEffect(() => {
const hasFilters = Boolean(filters && filters.length > 0);
const hasQuery = Boolean(query && query.query);
setHasFiltersOrQuery(hasFilters || hasQuery);
}, [filters, onClearSavedQuery, query, savedQuery]);
const getDateRange = () => {
const defaultTimeSetting = uiSettings!.get(UI_SETTINGS.TIMEPICKER_TIME_DEFAULTS);
return {
from: dateRangeFrom || defaultTimeSetting.from,
to: dateRangeTo || defaultTimeSetting.to,
};
};
const onEnableAll = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:enable_all`);
const enabledFilters = filters?.map(enableFilter);
if (enabledFilters) {
onFiltersUpdated?.(enabledFilters);
}
};
const onDisableAll = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:disable_all`);
const disabledFilters = filters?.map(disableFilter);
if (disabledFilters) {
onFiltersUpdated?.(disabledFilters);
}
};
const onToggleAllNegated = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:invert_all`);
const negatedFilters = filters?.map(toggleFilterNegated);
if (negatedFilters) {
onFiltersUpdated?.(negatedFilters);
}
};
const onRemoveAll = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:remove_all`);
onFiltersUpdated?.([]);
};
const onPinAll = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:pin_all`);
const pinnedFilters = filters?.map(pinFilter);
if (pinnedFilters) {
onFiltersUpdated?.(pinnedFilters);
}
};
const onUnpinAll = () => {
reportUiCounter?.(METRIC_TYPE.CLICK, `filter:unpin_all`);
const unPinnedFilters = filters?.map(unpinFilter);
if (unPinnedFilters) {
onFiltersUpdated?.(unPinnedFilters);
}
};
const onQueryStringChange = (value: string) => {
onQueryChange({
query: { query: value, language },
dateRange: getDateRange(),
});
};
const onSelectLanguage = (lang: string) => {
http.post('/internal/kql_opt_in_stats', {
version: KQL_TELEMETRY_ROUTE_LATEST_VERSION,
body: JSON.stringify({ opt_in: lang === 'kuery' }),
});
const storageKey = KIBANA_USER_QUERY_LANGUAGE_KEY;
storage.set(storageKey!, lang);
const newQuery = { query: '', language: lang };
onQueryStringChange(newQuery.query);
onQueryBarSubmit({
query: { query: fromUser(newQuery.query), language: newQuery.language },
dateRange: getDateRange(),
});
};
const luceneLabel = strings.getLuceneLanguageName();
const kqlLabel = strings.getKqlLanguageName();
const filtersRelatedPanels: EuiContextMenuPanelItemDescriptor[] = [
{
name: strings.getOptionsAddFilterButtonLabel(),
icon: 'plus',
onClick: () => {
setRenderedComponent('addFilter');
},
},
{
name: strings.getOptionsApplyAllFiltersButtonLabel(),
icon: 'filter',
panel: QueryBarMenuPanel.applyToAllFilters,
disabled: !Boolean(filters && filters.length > 0),
'data-test-subj': 'filter-sets-applyToAllFilters',
},
];
const queryAndFiltersRelatedPanels: EuiContextMenuPanelItemDescriptor[] = [
{
name: savedQuery
? strings.getLoadOtherFilterSetLabel()
: strings.getLoadCurrentFilterSetLabel(),
panel: QueryBarMenuPanel.loadQuery,
icon: 'filter',
'data-test-subj': 'saved-query-management-load-button',
disabled: !hasSavedQueries || !Boolean(manageFilterSetComponent),
},
{
name: savedQuery ? strings.getSaveAsNewFilterSetLabel() : strings.getSaveFilterSetLabel(),
icon: 'save',
disabled:
!Boolean(showSaveQuery) || !hasFiltersOrQuery || (savedQuery && !savedQueryHasChanged),
panel: QueryBarMenuPanel.saveAsNewQuery,
'data-test-subj': 'saved-query-management-save-button',
},
{ isSeparator: true },
];
const items: EuiContextMenuPanelItemDescriptor[] = [];
// apply to all actions are only shown when there are filters
if (showFilterBar) {
items.push(...filtersRelatedPanels);
}
// clear all actions are only shown when there are filters or query
if (showFilterBar || showQueryInput) {
items.push(
{
name: strings.getClearAllFiltersButtonLabel(),
disabled: !hasFiltersOrQuery && !Boolean(savedQuery),
icon: 'cross',
'data-test-subj': 'filter-sets-removeAllFilters',
onClick: () => {
closePopover();
onQueryBarSubmit({
query: { query: '', language },
dateRange: getDateRange(),
});
onRemoveAll();
onClearSavedQuery?.();
},
},
{ isSeparator: true }
);
}
if (showFilterBar && additionalQueryBarMenuItems.items?.length) {
items.push(...[...additionalQueryBarMenuItems.items, { isSeparator: true } as const]);
}
// saved queries actions are only shown when the showQueryInput and showFilterBar is true
if (showSavedQueries) {
items.push(...queryAndFiltersRelatedPanels);
}
// language menu appears when the showQueryInput is true
if (showQueryInput && !disableQueryLanguageSwitcher) {
items.push({
name: `Language: ${language === 'kuery' ? kqlLabel : luceneLabel}`,
panel: QueryBarMenuPanel.selectLanguage,
'data-test-subj': 'switchQueryLanguageButton',
});
}
let panels: EuiContextMenuPanelDescriptor[] = [
{
id: QueryBarMenuPanel.main,
title: savedQuery?.attributes.title ? (
<>
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiText
color={savedQuery ? 'primary' : 'default'}
size="s"
data-test-subj="savedQueryTitle"
>
<strong>{savedQuery.attributes.title}</strong>
</EuiText>
</EuiFlexItem>
{savedQuery && savedQueryHasChanged && Boolean(showSaveQuery) && hasFiltersOrQuery && (
<EuiFlexItem grow={false}>
<EuiButton
size="s"
fill
onClick={() => {
queryBarMenuRef.current?.showPanel(
QueryBarMenuPanel.updateCurrentQuery,
'next'
);
}}
aria-label={strings.getSavedQueryPopoverSaveChangesButtonAriaLabel(
savedQuery?.attributes.title
)}
data-test-subj="saved-query-management-save-changes-button"
>
{strings.getSavedQueryPopoverSaveChangesButtonText()}
</EuiButton>
</EuiFlexItem>
)}
</EuiFlexGroup>
</>
) : undefined,
items,
},
{
id: QueryBarMenuPanel.applyToAllFilters,
initialFocusedItemIndex: 1,
title: strings.getApplyAllFiltersButtonLabel(),
items: [
{
name: strings.getEnableAllFiltersButtonLabel(),
icon: 'eye',
'data-test-subj': 'filter-sets-enableAllFilters',
onClick: () => {
closePopover();
onEnableAll();
},
},
{
name: strings.getDisableAllFiltersButtonLabel(),
'data-test-subj': 'filter-sets-disableAllFilters',
icon: 'eyeClosed',
onClick: () => {
closePopover();
onDisableAll();
},
},
{
name: strings.getInvertNegatedFiltersButtonLabel(),
'data-test-subj': 'filter-sets-invertAllFilters',
icon: 'invert',
onClick: () => {
closePopover();
onToggleAllNegated();
},
},
{
name: strings.getPinAllFiltersButtonLabel(),
'data-test-subj': 'filter-sets-pinAllFilters',
icon: 'pin',
onClick: () => {
closePopover();
onPinAll();
},
},
{
name: strings.getUnpinAllFiltersButtonLabel(),
'data-test-subj': 'filter-sets-unpinAllFilters',
icon: 'pin',
onClick: () => {
closePopover();
onUnpinAll();
},
},
],
},
{
id: QueryBarMenuPanel.updateCurrentQuery,
content: (
<>
<PanelTitle
queryBarMenuRef={queryBarMenuRef}
title={strings.getSavedQueryPopoverSaveChangesButtonText()}
/>
<div css={{ padding: euiThemeVars.euiSizeM }}>{saveFormComponent}</div>
</>
),
},
{
id: QueryBarMenuPanel.saveAsNewQuery,
title: strings.getSaveCurrentFilterSetLabel(),
content: <div css={{ padding: euiThemeVars.euiSizeM }}>{saveAsNewQueryFormComponent}</div>,
},
{
id: QueryBarMenuPanel.loadQuery,
width: 400,
content: <div>{manageFilterSetComponent}</div>,
},
{
id: QueryBarMenuPanel.selectLanguage,
title: strings.getFilterLanguageLabel(),
content: (
<QueryLanguageSwitcher
language={language}
onSelectLanguage={onSelectLanguage}
nonKqlMode={nonKqlMode}
isOnTopBarMenu={true}
deps={{
docLinks: kibana.services.docLinks,
}}
/>
),
},
{
id: 4,
title: strings.getLoadCurrentFilterSetLabel(),
width: 400,
content: <div>{manageFilterSetComponent}</div>,
},
...(additionalQueryBarMenuItems.panels ?? []),
] as EuiContextMenuPanelDescriptor[];
if (hiddenPanelOptions && hiddenPanelOptions.length > 0) {
panels = panels.map((panel) => ({
...panel,
items: panel.items?.filter((panelItem) => {
if (!panelItem['data-test-subj']) {
return true;
}
const panelFilterOption = MAP_ITEMS_TO_FILTER_OPTION[panelItem['data-test-subj']];
if (!panelFilterOption) {
return true;
}
return !hiddenPanelOptions.includes(panelFilterOption);
}),
}));
}
return panels;
}