[APM] Turn 'fast filter' on by default and ensure tech preview badge shows when turned on (#193710)

closes https://github.com/elastic/kibana/issues/193406

<img width="1057" alt="Screenshot 2024-09-23 at 12 37 41"
src="https://github.com/user-attachments/assets/189eef68-e5ab-4472-a924-8c417960b09b">
<img width="1077" alt="Screenshot 2024-09-23 at 12 37 56"
src="https://github.com/user-attachments/assets/c0129aeb-2bb3-4055-a6f9-ccbbdb608451">
<img width="1202" alt="Screenshot 2024-09-23 at 12 38 04"
src="https://github.com/user-attachments/assets/ec2b1fa7-0342-440b-966c-965d24ef61c2">
This commit is contained in:
Cauê Marcondes 2024-09-23 16:54:50 +01:00 committed by GitHub
parent 1cd0531a6a
commit 886d009418
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 360 additions and 432 deletions

View file

@ -119,10 +119,8 @@ describe.skip('Service inventory', () => {
cy.loginAsEditorUser();
});
it('Toggles fast filter when clicking on link', () => {
it('Uses the fast filter to search for services', () => {
cy.visitKibana(serviceInventoryHref);
cy.get('[data-test-subj="tableSearchInput"]').should('not.exist');
cy.contains('Enable fast filter').click();
cy.get('[data-test-subj="tableSearchInput"]').should('exist');
cy.contains('opbeans-node');
cy.contains('opbeans-java');
@ -135,20 +133,6 @@ describe.skip('Service inventory', () => {
cy.contains('opbeans-node');
cy.contains('opbeans-java');
cy.contains('opbeans-rum');
cy.contains('Disable fast filter').click();
cy.get('[data-test-subj="tableSearchInput"]').should('not.exist');
});
});
describe('Table search with viewer user', () => {
beforeEach(() => {
cy.loginAsViewerUser();
});
it('Should not be able to turn it on', () => {
cy.visitKibana(serviceInventoryHref);
cy.get('[data-test-subj="tableSearchInput"]').should('not.exist');
cy.get('[data-test-subj="apmLink"]').should('be.disabled');
});
});

View file

@ -5,13 +5,11 @@
* 2.0.
*/
import { usePerformanceContext } from '@kbn/ebt-tools';
import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { usePerformanceContext } from '@kbn/ebt-tools';
import { i18n } from '@kbn/i18n';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { apmEnableServiceInventoryTableSearchBar } from '@kbn/observability-plugin/common';
import { useEditableSettings } from '@kbn/observability-shared-plugin/public';
import { ApmDocumentType } from '../../../../../common/document_type';
import {
ServiceInventoryFieldName,
@ -182,9 +180,7 @@ function useServicesDetailedStatisticsFetcher({
export function ApmServiceInventory() {
const [debouncedSearchQuery, setDebouncedSearchQuery] = useStateDebounced('');
const { onPageReady } = usePerformanceContext();
const [renderedItems, setRenderedItems] = useState<ServiceListItem[]>([]);
const mainStatisticsFetch = useServicesMainStatisticsFetcher(debouncedSearchQuery);
const { mainStatisticsData, mainStatisticsStatus } = mainStatisticsFetch;
@ -296,19 +292,9 @@ export function ApmServiceInventory() {
}
}, [mainStatisticsStatus, comparisonFetch.status, onPageReady]);
const { fields, isSaving, saveSingleSetting } = useEditableSettings([
apmEnableServiceInventoryTableSearchBar,
]);
const settingsField = fields[apmEnableServiceInventoryTableSearchBar];
const isTableSearchBarEnabled = Boolean(settingsField?.savedValue ?? settingsField?.defaultValue);
return (
<>
{/* keep this div as we're collecting telemetry to track the usage of the table fast search vs KQL bar */}
<div data-fastSearch={isTableSearchBarEnabled ? 'enabled' : 'disabled'}>
<SearchBar showTimeComparison />
</div>
<SearchBar showTimeComparison />
<EuiFlexGroup direction="column" gutterSize="m">
{displayMlCallout && mlCallout}
<EuiFlexItem>
@ -328,11 +314,6 @@ export function ApmServiceInventory() {
onChangeSearchQuery={setDebouncedSearchQuery}
maxCountExceeded={mainStatisticsData?.maxCountExceeded ?? false}
onChangeRenderedItems={setRenderedItems}
isTableSearchBarEnabled={isTableSearchBarEnabled}
isSavingSetting={isSaving}
onChangeTableSearchBarVisibility={() => {
saveSingleSetting(apmEnableServiceInventoryTableSearchBar, !isTableSearchBarEnabled);
}}
/>
</EuiFlexItem>
</EuiFlexGroup>

View file

@ -10,18 +10,16 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiIconTip,
EuiLink,
EuiSpacer,
EuiText,
EuiToolTip,
RIGHT_ALIGNMENT,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { getSurveyFeedbackURL } from '@kbn/observability-shared-plugin/public';
import { apmEnableServiceInventoryTableSearchBar } from '@kbn/observability-plugin/common';
import { ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils';
import { TypeOf } from '@kbn/typed-react-router-config';
import { omit } from 'lodash';
import React, { useContext, useMemo } from 'react';
import React, { useMemo } from 'react';
import { ServiceHealthStatus } from '../../../../../../common/service_health_status';
import {
ServiceInventoryFieldName,
@ -33,7 +31,7 @@ import {
asPercent,
asTransactionRate,
} from '../../../../../../common/utils/formatters';
import { KibanaEnvironmentContext } from '../../../../../context/kibana_environment_context/kibana_environment_context';
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
import { useApmParams } from '../../../../../hooks/use_apm_params';
import { useApmRouter } from '../../../../../hooks/use_apm_router';
import { Breakpoints, useBreakpoints } from '../../../../../hooks/use_breakpoints';
@ -56,9 +54,8 @@ import {
SortFunction,
TableSearchBar,
} from '../../../../shared/managed_table';
import { TryItButton } from '../../../../shared/try_it_button';
import { HealthBadge } from './health_badge';
import { ColumnHeaderWithTooltip } from './column_header_with_tooltip';
import { HealthBadge } from './health_badge';
type ServicesDetailedStatisticsAPIResponse =
APIReturnType<'POST /internal/apm/services/detailed_statistics'>;
@ -305,9 +302,6 @@ interface Props {
maxCountExceeded: boolean;
onChangeSearchQuery: (searchQuery: string) => void;
onChangeRenderedItems: (renderedItems: ServiceListItem[]) => void;
isTableSearchBarEnabled: boolean;
isSavingSetting: boolean;
onChangeTableSearchBarVisibility: () => void;
}
export function ApmServicesTable({
status,
@ -325,17 +319,13 @@ export function ApmServicesTable({
maxCountExceeded,
onChangeSearchQuery,
onChangeRenderedItems,
isTableSearchBarEnabled,
isSavingSetting,
onChangeTableSearchBarVisibility,
}: Props) {
const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext);
const breakpoints = useBreakpoints();
const { core } = useApmPluginContext();
const { link } = useApmRouter();
const showTransactionTypeColumn = items.some(
({ transactionType }) => transactionType && !isDefaultTransactionType(transactionType)
);
const { query } = useApmParams('/services');
const { kuery } = query;
const { fallbackToTransactions } = useFallbackToTransactionsFetcher({
@ -367,6 +357,11 @@ export function ApmServicesTable({
serviceOverflowCount,
]);
const isTableSearchBarEnabled = core.uiSettings.get<boolean>(
apmEnableServiceInventoryTableSearchBar,
true
);
const tableSearchBar: TableSearchBar<ServiceListItem> = useMemo(() => {
return {
isEnabled: isTableSearchBarEnabled,
@ -376,56 +371,12 @@ export function ApmServicesTable({
placeholder: i18n.translate('xpack.apm.servicesTable.filterServicesPlaceholder', {
defaultMessage: 'Search services by name',
}),
techPreview: true,
};
}, [isTableSearchBarEnabled, maxCountExceeded, onChangeSearchQuery]);
return (
<EuiFlexGroup gutterSize="xs" direction="column" responsive={false}>
<EuiFlexItem>
<TryItButton
isFeatureEnabled={isTableSearchBarEnabled}
linkLabel={
isTableSearchBarEnabled
? i18n.translate('xpack.apm.serviceList.disableFastFilter', {
defaultMessage: 'Disable fast filter',
})
: i18n.translate('xpack.apm.serviceList.enableFastFilter', {
defaultMessage: 'Enable fast filter',
})
}
onClick={onChangeTableSearchBarVisibility}
isLoading={isSavingSetting}
popoverContent={
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem grow={false}>
{i18n.translate('xpack.apm.serviceList.turnOffFastFilter', {
defaultMessage:
'Fast filtering allows you to instantly search for your services using free text.',
})}
</EuiFlexItem>
{isTableSearchBarEnabled && (
<EuiFlexItem grow={false}>
<EuiLink
data-test-subj="apmServiceListGiveFeedbackLink"
href={getSurveyFeedbackURL({
formUrl: 'https://ela.st/service-inventory-fast-filter-feedback',
kibanaVersion,
isCloudEnv,
isServerlessEnv,
})}
target="_blank"
>
{i18n.translate('xpack.apm.serviceList.giveFeedbackFlexItemLabel', {
defaultMessage: 'Give feedback',
})}
</EuiLink>
</EuiFlexItem>
)}
</EuiFlexGroup>
}
/>
<EuiSpacer size="s" />
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup alignItems="center" gutterSize="xs" justifyContent="flexEnd">
{fallbackToTransactions && (

View file

@ -43,6 +43,7 @@ export interface TableSearchBar<T> {
maxCountExceeded: boolean;
placeholder: string;
onChangeSearchQuery: (searchQuery: string) => void;
techPreview?: boolean;
}
const PAGE_SIZE_OPTIONS = [10, 25, 50];
@ -265,6 +266,7 @@ function UnoptimizedManagedTable<T extends object>(props: {
placeholder={tableSearchBar.placeholder}
searchQuery={searchQuery}
onChangeSearchQuery={onChangeSearchQuery}
techPreview={tableSearchBar.techPreview}
/>
) : null}

View file

@ -4,26 +4,48 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { EuiFieldSearch } from '@elastic/eui';
import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React from 'react';
import { css } from '@emotion/react';
import { TechnicalPreviewBadge } from '../technical_preview_badge';
interface Props {
placeholder: string;
searchQuery: string;
onChangeSearchQuery: (value: string) => void;
techPreview?: boolean;
}
export function TableSearchBar({ placeholder, searchQuery, onChangeSearchQuery }: Props) {
export function TableSearchBar({
placeholder,
searchQuery,
onChangeSearchQuery,
techPreview = false,
}: Props) {
return (
<EuiFieldSearch
data-test-subj="tableSearchInput"
placeholder={placeholder}
fullWidth={true}
value={searchQuery}
onChange={(e) => {
onChangeSearchQuery(e.target.value);
}}
/>
<EuiFlexGroup gutterSize="s">
{techPreview ? (
<EuiFlexItem
grow={false}
css={css`
justify-content: center;
`}
>
<TechnicalPreviewBadge icon="beaker" />
</EuiFlexItem>
) : null}
<EuiFlexItem>
<EuiFieldSearch
data-test-subj="tableSearchInput"
placeholder={placeholder}
fullWidth={true}
value={searchQuery}
onChange={(e) => {
onChangeSearchQuery(e.target.value);
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
}

View file

@ -372,8 +372,8 @@ export const uiSettings: Record<string, UiSettings> = {
}
),
schema: schema.boolean(),
value: false,
requiresPageReload: false,
value: true,
requiresPageReload: true,
type: 'boolean',
},
[apmAWSLambdaPriceFactor]: {

File diff suppressed because one or more lines are too long

View file

@ -2699,6 +2699,28 @@
"embeddableApi.selectRangeTrigger.title": "範囲選択",
"embeddableApi.valueClickTrigger.description": "ビジュアライゼーションでデータポイントをクリック",
"embeddableApi.valueClickTrigger.title": "シングルクリック",
"esqlEditor.query.aborted": "リクエストが中断されました",
"esqlEditor.query.EnableWordWrapLabel": "パイプの改行を追加",
"esqlEditor.query.errorCount": "{count} {count, plural, other {# 件のエラー}}",
"esqlEditor.query.errorsTitle": "エラー",
"esqlEditor.query.expandLabel": "拡張",
"esqlEditor.query.feedback": "フィードバック",
"esqlEditor.query.hideQueriesLabel": "最近のクエリーを非表示",
"esqlEditor.query.lineCount": "{count} {count, plural, other {行}}",
"esqlEditor.query.lineNumber": "行{lineNumber}",
"esqlEditor.query.querieshistory.error": "クエリ失敗",
"esqlEditor.query.querieshistory.success": "クエリは正常に実行されました",
"esqlEditor.query.querieshistoryCopy": "クエリをクリップボードにコピー",
"esqlEditor.query.querieshistoryRun": "クエリーを実行",
"esqlEditor.query.querieshistoryTable": "クエリ履歴テーブル",
"esqlEditor.query.recentQueriesColumnLabel": "最近のクエリー",
"esqlEditor.query.runQuery": "クエリーを実行",
"esqlEditor.query.showQueriesLabel": "最近のクエリを表示",
"esqlEditor.query.submitFeedback": "フィードバックを送信",
"esqlEditor.query.timeRanColumnLabel": "実行時間",
"esqlEditor.query.timestampNotDetected": "@timestampが見つかりません",
"esqlEditor.query.warningCount": "{count} {count, plural, other {件の警告}}",
"esqlEditor.query.warningsTitle": "警告",
"esqlUtils.columnsErrorMsg": "列を読み込めません。{errorMessage}",
"esQuery.kql.errors.endOfInputText": "インプットの終わり",
"esQuery.kql.errors.fieldNameText": "フィールド名",
@ -7076,28 +7098,6 @@
"telemetry.telemetryOptedInNoticeTitle": "Elastic Stack の改善にご協力ください",
"telemetry.usageCollectionConstant": "使用状況の収集",
"telemetry.usageDataTitle": "使用状況の収集",
"esqlEditor.query.aborted": "リクエストが中断されました",
"esqlEditor.query.EnableWordWrapLabel": "パイプの改行を追加",
"esqlEditor.query.errorCount": "{count} {count, plural, other {# 件のエラー}}",
"esqlEditor.query.errorsTitle": "エラー",
"esqlEditor.query.expandLabel": "拡張",
"esqlEditor.query.feedback": "フィードバック",
"esqlEditor.query.hideQueriesLabel": "最近のクエリーを非表示",
"esqlEditor.query.lineCount": "{count} {count, plural, other {行}}",
"esqlEditor.query.lineNumber": "行{lineNumber}",
"esqlEditor.query.querieshistory.error": "クエリ失敗",
"esqlEditor.query.querieshistory.success": "クエリは正常に実行されました",
"esqlEditor.query.querieshistoryCopy": "クエリをクリップボードにコピー",
"esqlEditor.query.querieshistoryRun": "クエリーを実行",
"esqlEditor.query.querieshistoryTable": "クエリ履歴テーブル",
"esqlEditor.query.recentQueriesColumnLabel": "最近のクエリー",
"esqlEditor.query.runQuery": "クエリーを実行",
"esqlEditor.query.showQueriesLabel": "最近のクエリを表示",
"esqlEditor.query.submitFeedback": "フィードバックを送信",
"esqlEditor.query.timeRanColumnLabel": "実行時間",
"esqlEditor.query.timestampNotDetected": "@timestampが見つかりません",
"esqlEditor.query.warningCount": "{count} {count, plural, other {件の警告}}",
"esqlEditor.query.warningsTitle": "警告",
"timelion.emptyExpressionErrorMessage": "Timelion エラー:式が入力されていません",
"timelion.expressionSuggestions.argument.description.acceptsText": "受け入れ",
"timelion.expressionSuggestions.func.description.chainableHelpText": "連鎖可能",
@ -10720,10 +10720,6 @@
"xpack.apm.serviceIcons.serviceDetails.service.versionLabel": "サービスバージョン",
"xpack.apm.serviceLink.otherBucketName": "残りのサービス",
"xpack.apm.serviceLink.tooltip": "実行されたサービス数がAPMサーバーの現在の能力に達しました。",
"xpack.apm.serviceList.disableFastFilter": "高速フィルターを無効化",
"xpack.apm.serviceList.enableFastFilter": "高速フィルターを有効化",
"xpack.apm.serviceList.giveFeedbackFlexItemLabel": "フィードバックを作成する",
"xpack.apm.serviceList.turnOffFastFilter": "高速フィルタリングでは、フリーテキストを使用してサービスを瞬時に検索できます。",
"xpack.apm.serviceMap.anomalyDetectionPopoverDisabled": "APM 設定で異常検知を有効にすると、サービス正常性インジケーターが表示されます。",
"xpack.apm.serviceMap.anomalyDetectionPopoverLink": "異常を表示",
"xpack.apm.serviceMap.anomalyDetectionPopoverNoData": "選択した時間範囲で、異常スコアを検出できませんでした。異常エクスプローラーで詳細を確認してください。",

View file

@ -2705,6 +2705,31 @@
"embeddableApi.selectRangeTrigger.title": "范围选择",
"embeddableApi.valueClickTrigger.description": "可视化上的数据点单击",
"embeddableApi.valueClickTrigger.title": "单击",
"esqlEditor.query.aborted": "请求已中止",
"esqlEditor.query.cancel": "取消",
"esqlEditor.query.collapseLabel": "折叠",
"esqlEditor.query.disableWordWrapLabel": "移除管道符上的换行符",
"esqlEditor.query.EnableWordWrapLabel": "在管道符上添加换行符",
"esqlEditor.query.errorCount": "{count} 个{count, plural, other {错误}}",
"esqlEditor.query.errorsTitle": "错误",
"esqlEditor.query.expandLabel": "展开",
"esqlEditor.query.feedback": "反馈",
"esqlEditor.query.hideQueriesLabel": "隐藏最近查询",
"esqlEditor.query.lineCount": "{count} {count, plural, other {行}}",
"esqlEditor.query.lineNumber": "第 {lineNumber} 行",
"esqlEditor.query.querieshistory.error": "查询失败",
"esqlEditor.query.querieshistory.success": "已成功运行查询",
"esqlEditor.query.querieshistoryCopy": "复制查询到剪贴板",
"esqlEditor.query.querieshistoryRun": "运行查询",
"esqlEditor.query.querieshistoryTable": "查询历史记录表",
"esqlEditor.query.recentQueriesColumnLabel": "最近查询",
"esqlEditor.query.runQuery": "运行查询",
"esqlEditor.query.showQueriesLabel": "显示最近查询",
"esqlEditor.query.submitFeedback": "提交反馈",
"esqlEditor.query.timeRanColumnLabel": "运行时间",
"esqlEditor.query.timestampNotDetected": "未找到 @timestamp",
"esqlEditor.query.warningCount": "{count} 个{count, plural, other {警告}}",
"esqlEditor.query.warningsTitle": "警告",
"esqlUtils.columnsErrorMsg": "无法加载列。{errorMessage}",
"esQuery.kql.errors.endOfInputText": "输入结束",
"esQuery.kql.errors.fieldNameText": "字段名称",
@ -7089,31 +7114,6 @@
"telemetry.telemetryOptedInNoticeTitle": "帮助我们改进 Elastic Stack",
"telemetry.usageCollectionConstant": "使用情况收集",
"telemetry.usageDataTitle": "使用情况收集",
"esqlEditor.query.aborted": "请求已中止",
"esqlEditor.query.cancel": "取消",
"esqlEditor.query.collapseLabel": "折叠",
"esqlEditor.query.disableWordWrapLabel": "移除管道符上的换行符",
"esqlEditor.query.EnableWordWrapLabel": "在管道符上添加换行符",
"esqlEditor.query.errorCount": "{count} 个{count, plural, other {错误}}",
"esqlEditor.query.errorsTitle": "错误",
"esqlEditor.query.expandLabel": "展开",
"esqlEditor.query.feedback": "反馈",
"esqlEditor.query.hideQueriesLabel": "隐藏最近查询",
"esqlEditor.query.lineCount": "{count} {count, plural, other {行}}",
"esqlEditor.query.lineNumber": "第 {lineNumber} 行",
"esqlEditor.query.querieshistory.error": "查询失败",
"esqlEditor.query.querieshistory.success": "已成功运行查询",
"esqlEditor.query.querieshistoryCopy": "复制查询到剪贴板",
"esqlEditor.query.querieshistoryRun": "运行查询",
"esqlEditor.query.querieshistoryTable": "查询历史记录表",
"esqlEditor.query.recentQueriesColumnLabel": "最近查询",
"esqlEditor.query.runQuery": "运行查询",
"esqlEditor.query.showQueriesLabel": "显示最近查询",
"esqlEditor.query.submitFeedback": "提交反馈",
"esqlEditor.query.timeRanColumnLabel": "运行时间",
"esqlEditor.query.timestampNotDetected": "未找到 @timestamp",
"esqlEditor.query.warningCount": "{count} 个{count, plural, other {警告}}",
"esqlEditor.query.warningsTitle": "警告",
"timelion.emptyExpressionErrorMessage": "Timelion 错误:未提供表达式",
"timelion.expressionSuggestions.argument.description.acceptsText": "接受",
"timelion.expressionSuggestions.func.description.chainableHelpText": "可串接",
@ -10742,10 +10742,6 @@
"xpack.apm.serviceIcons.serviceDetails.service.versionLabel": "服务版本",
"xpack.apm.serviceLink.otherBucketName": "剩余服务",
"xpack.apm.serviceLink.tooltip": "检测的服务数已达到 APM 服务器的当前容量",
"xpack.apm.serviceList.disableFastFilter": "禁用快速筛选",
"xpack.apm.serviceList.enableFastFilter": "启用快速筛选",
"xpack.apm.serviceList.giveFeedbackFlexItemLabel": "反馈",
"xpack.apm.serviceList.turnOffFastFilter": "借助快速筛选,您可以立即使用自定义文本搜索服务。",
"xpack.apm.serviceMap.anomalyDetectionPopoverDisabled": "通过在 APM 设置中启用异常检测来显示服务运行状况指标。",
"xpack.apm.serviceMap.anomalyDetectionPopoverLink": "查看异常",
"xpack.apm.serviceMap.anomalyDetectionPopoverNoData": "在选定时间范围内找不到异常分数。请在 Anomaly Explorer 中查看详情。",