mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Exploratory view] Url filter wildcard (#114797)
This commit is contained in:
parent
45c3d2b017
commit
72dcc4638b
27 changed files with 1571 additions and 1007 deletions
|
@ -14,6 +14,7 @@ import { FilterValueLabel } from '../../../../../../observability/public';
|
|||
import { FiltersUIHook } from '../hooks/useLocalUIFilters';
|
||||
import { UxLocalUIFilterName } from '../../../../../common/ux_ui_filter';
|
||||
import { IndexPattern } from '../../../../../../../../src/plugins/data/common';
|
||||
import { SelectedWildcards } from './selected_wildcards';
|
||||
|
||||
interface Props {
|
||||
indexPattern?: IndexPattern;
|
||||
|
@ -34,15 +35,19 @@ export function SelectedFilters({
|
|||
invertFilter,
|
||||
clearValues,
|
||||
}: Props) {
|
||||
const { uxUiFilters } = useUrlParams();
|
||||
const {
|
||||
uxUiFilters,
|
||||
urlParams: { searchTerm },
|
||||
} = useUrlParams();
|
||||
const { transactionUrl } = uxUiFilters;
|
||||
|
||||
const urlValues = transactionUrl ?? [];
|
||||
|
||||
const hasValues = filters.some((filter) => filter.value?.length > 0);
|
||||
|
||||
return indexPattern && (hasValues || urlValues.length > 0) ? (
|
||||
return indexPattern && (hasValues || urlValues.length > 0 || searchTerm) ? (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" wrap>
|
||||
<SelectedWildcards indexPattern={indexPattern} />
|
||||
{(filters ?? []).map(({ name, title, fieldName, excluded }) => (
|
||||
<Fragment key={name}>
|
||||
{((uxUiFilters?.[name] ?? []) as string[]).map((value) => (
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { FilterValueLabel } from '../../../../../../observability/public';
|
||||
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
|
||||
import { TRANSACTION_URL } from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { IndexPattern } from '../../../../../../../../src/plugins/data_views/common';
|
||||
|
||||
interface Props {
|
||||
indexPattern: IndexPattern;
|
||||
}
|
||||
export function SelectedWildcards({ indexPattern }: Props) {
|
||||
const history = useHistory();
|
||||
|
||||
const {
|
||||
urlParams: { searchTerm },
|
||||
} = useUrlParams();
|
||||
|
||||
const updateSearchTerm = useCallback(
|
||||
(searchTermN: string) => {
|
||||
const newQuery = {
|
||||
...toQuery(history.location.search),
|
||||
searchTerm: searchTermN || undefined,
|
||||
};
|
||||
if (!searchTermN) {
|
||||
delete newQuery.searchTerm;
|
||||
}
|
||||
const newLocation = {
|
||||
...history.location,
|
||||
search: fromQuery(newQuery),
|
||||
};
|
||||
history.push(newLocation);
|
||||
},
|
||||
[history]
|
||||
);
|
||||
|
||||
return searchTerm ? (
|
||||
<FilterValueLabel
|
||||
indexPattern={indexPattern}
|
||||
removeFilter={() => {
|
||||
updateSearchTerm('');
|
||||
}}
|
||||
invertFilter={({ negate }) => {}}
|
||||
field={TRANSACTION_URL}
|
||||
value={searchTerm}
|
||||
negate={false}
|
||||
label={'URL wildcard'}
|
||||
/>
|
||||
) : null;
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
fireEvent,
|
||||
waitFor,
|
||||
waitForElementToBeRemoved,
|
||||
screen,
|
||||
} from '@testing-library/react';
|
||||
import { __IntlProvider as IntlProvider } from '@kbn/i18n/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import * as fetcherHook from '../../../../../hooks/use_fetcher';
|
||||
import { SelectableUrlList } from './SelectableUrlList';
|
||||
import { render } from '../../utils/test_helper';
|
||||
import { I18LABELS } from '../../translations';
|
||||
|
||||
describe('SelectableUrlList', () => {
|
||||
jest.spyOn(fetcherHook, 'useFetcher').mockReturnValue({
|
||||
data: {},
|
||||
status: fetcherHook.FETCH_STATUS.SUCCESS,
|
||||
refetch: jest.fn(),
|
||||
});
|
||||
|
||||
const customHistory = createMemoryHistory({
|
||||
initialEntries: ['/?searchTerm=blog'],
|
||||
});
|
||||
|
||||
function WrappedComponent() {
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
return (
|
||||
<IntlProvider locale="en">
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
onTermChange={jest.fn()}
|
||||
popoverIsOpen={Boolean(isPopoverOpen)}
|
||||
setPopoverIsOpen={setIsPopoverOpen}
|
||||
onApply={jest.fn()}
|
||||
/>
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
|
||||
it('it uses search term value from url', () => {
|
||||
const { getByDisplayValue } = render(
|
||||
<IntlProvider locale="en">
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
onTermChange={jest.fn()}
|
||||
popoverIsOpen={false}
|
||||
setPopoverIsOpen={jest.fn()}
|
||||
onApply={jest.fn()}
|
||||
/>
|
||||
</IntlProvider>,
|
||||
{ customHistory }
|
||||
);
|
||||
expect(getByDisplayValue('blog')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('maintains focus on search input field', () => {
|
||||
const { getByLabelText } = render(
|
||||
<IntlProvider locale="en">
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
onTermChange={jest.fn()}
|
||||
popoverIsOpen={false}
|
||||
setPopoverIsOpen={jest.fn()}
|
||||
onApply={jest.fn()}
|
||||
/>
|
||||
</IntlProvider>,
|
||||
{ customHistory }
|
||||
);
|
||||
|
||||
const input = getByLabelText(I18LABELS.filterByUrl);
|
||||
fireEvent.click(input);
|
||||
|
||||
expect(document.activeElement).toBe(input);
|
||||
});
|
||||
|
||||
it('hides popover on escape', async () => {
|
||||
const { getByText, getByLabelText, queryByText } = render(
|
||||
<WrappedComponent />,
|
||||
{ customHistory }
|
||||
);
|
||||
|
||||
const input = getByLabelText(I18LABELS.filterByUrl);
|
||||
fireEvent.click(input);
|
||||
|
||||
// wait for title of popover to be present
|
||||
await waitFor(() => {
|
||||
expect(getByText(I18LABELS.getSearchResultsLabel(0))).toBeInTheDocument();
|
||||
screen.debug();
|
||||
});
|
||||
|
||||
// escape key
|
||||
fireEvent.keyDown(input, {
|
||||
key: 'Escape',
|
||||
code: 'Escape',
|
||||
keyCode: 27,
|
||||
charCode: 27,
|
||||
});
|
||||
|
||||
// wait for title of popover to be removed
|
||||
await waitForElementToBeRemoved(() =>
|
||||
queryByText(I18LABELS.getSearchResultsLabel(0))
|
||||
);
|
||||
});
|
||||
});
|
|
@ -5,17 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import React, { useEffect, useState, FormEvent } from 'react';
|
||||
import { map } from 'lodash';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { isEqual, map } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useUrlParams } from '../../../../../context/url_params_context/use_url_params';
|
||||
import { useFetcher } from '../../../../../hooks/use_fetcher';
|
||||
import { I18LABELS } from '../../translations';
|
||||
import { formatToSec } from '../../UXMetrics/KeyUXMetrics';
|
||||
import { SelectableUrlList } from './SelectableUrlList';
|
||||
import { UrlOption } from './RenderOption';
|
||||
import { useUxQuery } from '../../hooks/useUxQuery';
|
||||
import { getPercentileLabel } from '../../UXMetrics/translations';
|
||||
import { SelectableUrlList } from '../../../../../../../observability/public';
|
||||
import { selectableRenderOptions, UrlOption } from './render_option';
|
||||
import { useUrlSearch } from './use_url_search';
|
||||
|
||||
interface Props {
|
||||
onChange: (value?: string[], excludedValue?: string[]) => void;
|
||||
|
@ -38,6 +37,7 @@ const formatOptions = (
|
|||
|
||||
return urlItems.map((item) => ({
|
||||
label: item.url,
|
||||
title: item.url,
|
||||
key: item.url,
|
||||
meta: [
|
||||
I18LABELS.pageViews + ': ' + item.count,
|
||||
|
@ -55,124 +55,146 @@ const formatOptions = (
|
|||
}));
|
||||
};
|
||||
|
||||
const processItems = (items: UrlOption[]) => {
|
||||
const includedItems = map(
|
||||
items.filter(({ checked, isWildcard }) => checked === 'on' && !isWildcard),
|
||||
'label'
|
||||
);
|
||||
|
||||
const excludedItems = map(
|
||||
items.filter(({ checked, isWildcard }) => checked === 'off' && !isWildcard),
|
||||
'label'
|
||||
);
|
||||
|
||||
const includedWildcards = map(
|
||||
items.filter(({ checked, isWildcard }) => checked === 'on' && isWildcard),
|
||||
'title'
|
||||
);
|
||||
|
||||
const excludedWildcards = map(
|
||||
items.filter(({ checked, isWildcard }) => checked === 'off' && isWildcard),
|
||||
'title'
|
||||
);
|
||||
|
||||
return { includedItems, excludedItems, includedWildcards, excludedWildcards };
|
||||
};
|
||||
|
||||
const getWildcardLabel = (wildcard: string) => {
|
||||
return i18n.translate('xpack.apm.urlFilter.wildcard', {
|
||||
defaultMessage: 'Use wildcard *{wildcard}*',
|
||||
values: { wildcard },
|
||||
});
|
||||
};
|
||||
|
||||
export function URLSearch({
|
||||
onChange: onFilterChange,
|
||||
updateSearchTerm,
|
||||
}: Props) {
|
||||
const { uxUiFilters, urlParams } = useUrlParams();
|
||||
|
||||
const { transactionUrl, transactionUrlExcluded, ...restFilters } =
|
||||
uxUiFilters;
|
||||
const {
|
||||
uxUiFilters: { transactionUrl, transactionUrlExcluded },
|
||||
urlParams,
|
||||
} = useUrlParams();
|
||||
|
||||
const { searchTerm, percentile } = urlParams;
|
||||
|
||||
const [popoverIsOpen, setPopoverIsOpen] = useState<boolean>(false);
|
||||
|
||||
const [searchValue, setSearchValue] = useState(searchTerm ?? '');
|
||||
|
||||
const [debouncedValue, setDebouncedValue] = useState(searchTerm ?? '');
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
|
||||
const [items, setItems] = useState<UrlOption[]>([]);
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
setSearchValue(debouncedValue);
|
||||
},
|
||||
250,
|
||||
[debouncedValue]
|
||||
);
|
||||
|
||||
const uxQuery = useUxQuery();
|
||||
|
||||
const { data, status } = useFetcher(
|
||||
(callApmApi) => {
|
||||
if (uxQuery && popoverIsOpen) {
|
||||
return callApmApi({
|
||||
endpoint: 'GET /api/apm/rum-client/url-search',
|
||||
params: {
|
||||
query: {
|
||||
...uxQuery,
|
||||
uiFilters: JSON.stringify(restFilters),
|
||||
urlQuery: searchValue,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[uxQuery, searchValue, popoverIsOpen]
|
||||
);
|
||||
const { data, status } = useUrlSearch({ query: searchValue, popoverIsOpen });
|
||||
|
||||
useEffect(() => {
|
||||
setItems(
|
||||
formatOptions(
|
||||
data?.items ?? [],
|
||||
transactionUrl,
|
||||
transactionUrlExcluded,
|
||||
percentile
|
||||
)
|
||||
const newItems = formatOptions(
|
||||
data?.items ?? [],
|
||||
transactionUrl,
|
||||
transactionUrlExcluded,
|
||||
percentile
|
||||
);
|
||||
}, [data, percentile, transactionUrl, transactionUrlExcluded]);
|
||||
const wildCardLabel = searchValue || searchTerm;
|
||||
|
||||
useEffect(() => {
|
||||
if (searchTerm && searchValue === '') {
|
||||
updateSearchTerm('');
|
||||
if (wildCardLabel) {
|
||||
newItems.unshift({
|
||||
label: getWildcardLabel(wildCardLabel),
|
||||
title: wildCardLabel,
|
||||
isWildcard: true,
|
||||
checked: searchTerm ? 'on' : undefined,
|
||||
});
|
||||
}
|
||||
}, [searchValue, updateSearchTerm, searchTerm]);
|
||||
setItems(newItems);
|
||||
}, [
|
||||
data,
|
||||
percentile,
|
||||
searchTerm,
|
||||
searchValue,
|
||||
transactionUrl,
|
||||
transactionUrlExcluded,
|
||||
]);
|
||||
|
||||
const onChange = (updatedOptions: UrlOption[]) => {
|
||||
const includedItems = map(
|
||||
updatedOptions.filter((option) => option.checked === 'on'),
|
||||
'label'
|
||||
);
|
||||
|
||||
const excludedItems = map(
|
||||
updatedOptions.filter((option) => option.checked === 'off'),
|
||||
'label'
|
||||
);
|
||||
|
||||
setItems(
|
||||
formatOptions(data?.items ?? [], includedItems, excludedItems, percentile)
|
||||
updatedOptions.map((item) => {
|
||||
const { isWildcard, checked } = item;
|
||||
if (isWildcard && checked === 'off') {
|
||||
return {
|
||||
...item,
|
||||
checked: undefined,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const onInputChange = (e: FormEvent<HTMLInputElement>) => {
|
||||
setDebouncedValue(e.currentTarget.value);
|
||||
const onInputChange = (val: string) => {
|
||||
setSearchValue(val);
|
||||
};
|
||||
|
||||
const isLoading = status !== 'success';
|
||||
|
||||
const onTermChange = () => {
|
||||
updateSearchTerm(searchValue);
|
||||
};
|
||||
|
||||
const onApply = () => {
|
||||
const includedItems = map(
|
||||
items.filter((option) => option.checked === 'on'),
|
||||
'label'
|
||||
);
|
||||
|
||||
const excludedItems = map(
|
||||
items.filter((option) => option.checked === 'off'),
|
||||
'label'
|
||||
);
|
||||
const { includedItems, excludedItems } = processItems(items);
|
||||
|
||||
onFilterChange(includedItems, excludedItems);
|
||||
|
||||
updateSearchTerm(searchValue);
|
||||
|
||||
setSearchValue('');
|
||||
};
|
||||
|
||||
const hasChanged = () => {
|
||||
const { includedItems, excludedItems, includedWildcards } =
|
||||
processItems(items);
|
||||
|
||||
let isWildcardChanged =
|
||||
(includedWildcards.length > 0 && !searchTerm) ||
|
||||
(includedWildcards.length === 0 && searchTerm);
|
||||
|
||||
if (includedWildcards.length > 0) {
|
||||
isWildcardChanged = includedWildcards[0] !== searchTerm;
|
||||
}
|
||||
|
||||
return (
|
||||
isWildcardChanged ||
|
||||
!isEqual(includedItems.sort(), (transactionUrl ?? []).sort()) ||
|
||||
!isEqual(excludedItems.sort(), (transactionUrlExcluded ?? []).sort())
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SelectableUrlList
|
||||
initialValue={searchTerm}
|
||||
loading={isLoading}
|
||||
onInputChange={onInputChange}
|
||||
onTermChange={onTermChange}
|
||||
data={{ items, total: data?.total ?? 0 }}
|
||||
onChange={onChange}
|
||||
onSelectionChange={onChange}
|
||||
searchValue={searchValue}
|
||||
popoverIsOpen={Boolean(popoverIsOpen)}
|
||||
setPopoverIsOpen={setPopoverIsOpen}
|
||||
onApply={onApply}
|
||||
onSelectionApply={onApply}
|
||||
renderOption={selectableRenderOptions}
|
||||
rowHeight={64}
|
||||
hasChanged={() => Boolean(hasChanged())}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { EuiHighlight, EuiSelectableOption } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
|
||||
|
@ -27,19 +26,9 @@ const StyledListSpan = styled.span`
|
|||
`;
|
||||
export type UrlOption<T = { [key: string]: any }> = {
|
||||
meta?: string[];
|
||||
title: string;
|
||||
} & EuiSelectableOption<T>;
|
||||
|
||||
export const formatOptions = (options: EuiSelectableOption[]) => {
|
||||
return options.map((item: EuiSelectableOption) => ({
|
||||
title: item.label,
|
||||
...item,
|
||||
className: classNames(
|
||||
'euiSelectableTemplateSitewide__listItem',
|
||||
item.className
|
||||
),
|
||||
}));
|
||||
};
|
||||
|
||||
export function selectableRenderOptions(
|
||||
option: UrlOption,
|
||||
searchValue: string
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { useState } from 'react';
|
||||
import { useFetcher } from '../../../../../hooks/use_fetcher';
|
||||
import { useUxQuery } from '../../hooks/useUxQuery';
|
||||
import { useUrlParams } from '../../../../../context/url_params_context/use_url_params';
|
||||
|
||||
interface Props {
|
||||
popoverIsOpen: boolean;
|
||||
query: string;
|
||||
}
|
||||
|
||||
export const useUrlSearch = ({ popoverIsOpen, query }: Props) => {
|
||||
const uxQuery = useUxQuery();
|
||||
|
||||
const { uxUiFilters } = useUrlParams();
|
||||
|
||||
const { transactionUrl, transactionUrlExcluded, ...restFilters } =
|
||||
uxUiFilters;
|
||||
|
||||
const [searchValue, setSearchValue] = useState(query ?? '');
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
setSearchValue(query);
|
||||
},
|
||||
250,
|
||||
[query]
|
||||
);
|
||||
|
||||
return useFetcher(
|
||||
(callApmApi) => {
|
||||
if (uxQuery && popoverIsOpen) {
|
||||
return callApmApi({
|
||||
endpoint: 'GET /api/apm/rum-client/url-search',
|
||||
params: {
|
||||
query: {
|
||||
...uxQuery,
|
||||
uiFilters: JSON.stringify(restFilters),
|
||||
urlQuery: searchValue,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[uxQuery, searchValue, popoverIsOpen]
|
||||
);
|
||||
};
|
|
@ -81,6 +81,7 @@ export function useLocalUIFilters({
|
|||
const clearValues = () => {
|
||||
const search = omit(toQuery(history.location.search), [
|
||||
...filterNames,
|
||||
'searchTerm',
|
||||
'transactionUrl',
|
||||
]);
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { fireEvent, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import * as fetcherHook from '../../../../../hooks/use_fetcher';
|
||||
import { SelectableUrlList } from './selectable_url_list';
|
||||
import { I18LABELS } from './translations';
|
||||
import { render } from '../../rtl_helpers';
|
||||
|
||||
describe('SelectableUrlList', () => {
|
||||
jest.spyOn(fetcherHook, 'useFetcher').mockReturnValue({
|
||||
data: {},
|
||||
status: fetcherHook.FETCH_STATUS.SUCCESS,
|
||||
refetch: jest.fn(),
|
||||
});
|
||||
|
||||
const customHistory = createMemoryHistory({
|
||||
initialEntries: ['/?searchTerm=blog'],
|
||||
});
|
||||
|
||||
function WrappedComponent() {
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
return (
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onSelectionChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
popoverIsOpen={Boolean(isPopoverOpen)}
|
||||
setPopoverIsOpen={setIsPopoverOpen}
|
||||
onSelectionApply={jest.fn()}
|
||||
hasChanged={() => true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
it('it uses search term value from url', () => {
|
||||
const { getByDisplayValue } = render(
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onSelectionChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
popoverIsOpen={false}
|
||||
setPopoverIsOpen={jest.fn()}
|
||||
onSelectionApply={jest.fn()}
|
||||
hasChanged={() => true}
|
||||
/>,
|
||||
{ history: customHistory }
|
||||
);
|
||||
expect(getByDisplayValue('blog')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('maintains focus on search input field', () => {
|
||||
const { getByLabelText } = render(
|
||||
<SelectableUrlList
|
||||
initialValue={'blog'}
|
||||
loading={false}
|
||||
data={{ items: [], total: 0 }}
|
||||
onSelectionChange={jest.fn()}
|
||||
searchValue={'blog'}
|
||||
onInputChange={jest.fn()}
|
||||
popoverIsOpen={false}
|
||||
setPopoverIsOpen={jest.fn()}
|
||||
onSelectionApply={jest.fn()}
|
||||
hasChanged={() => true}
|
||||
/>,
|
||||
{ history: customHistory }
|
||||
);
|
||||
|
||||
const input = getByLabelText(I18LABELS.filterByUrl);
|
||||
fireEvent.click(input);
|
||||
|
||||
expect(document.activeElement).toBe(input);
|
||||
});
|
||||
|
||||
it('hides popover on escape', async () => {
|
||||
const { getByText, getByLabelText, queryByText } = render(<WrappedComponent />, {
|
||||
history: customHistory,
|
||||
});
|
||||
|
||||
const input = getByLabelText(I18LABELS.filterByUrl);
|
||||
fireEvent.click(input);
|
||||
|
||||
// wait for title of popover to be present
|
||||
await waitFor(() => {
|
||||
expect(getByText(I18LABELS.getSearchResultsLabel(0))).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// escape key
|
||||
fireEvent.keyDown(input, {
|
||||
key: 'Escape',
|
||||
code: 'Escape',
|
||||
keyCode: 27,
|
||||
charCode: 27,
|
||||
});
|
||||
|
||||
// wait for title of popover to be removed
|
||||
await waitForElementToBeRemoved(() => queryByText(I18LABELS.getSearchResultsLabel(0)));
|
||||
});
|
||||
});
|
|
@ -6,12 +6,13 @@
|
|||
*/
|
||||
|
||||
import React, {
|
||||
FormEvent,
|
||||
SetStateAction,
|
||||
useRef,
|
||||
useState,
|
||||
KeyboardEvent,
|
||||
useEffect,
|
||||
ReactNode,
|
||||
FormEventHandler,
|
||||
} from 'react';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
|
@ -23,71 +24,59 @@ import {
|
|||
EuiSelectableMessage,
|
||||
EuiPopoverFooter,
|
||||
EuiButton,
|
||||
EuiText,
|
||||
EuiIcon,
|
||||
EuiBadge,
|
||||
EuiButtonIcon,
|
||||
EuiSelectableOption,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import styled from 'styled-components';
|
||||
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
|
||||
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
|
||||
import useEvent from 'react-use/lib/useEvent';
|
||||
import {
|
||||
formatOptions,
|
||||
selectableRenderOptions,
|
||||
UrlOption,
|
||||
} from './RenderOption';
|
||||
import { I18LABELS } from '../../translations';
|
||||
import { useUiSetting$ } from '../../../../../../../../../src/plugins/kibana_react/public';
|
||||
import classNames from 'classnames';
|
||||
import { I18LABELS } from './translations';
|
||||
|
||||
const StyledRow = styled.div<{
|
||||
darkMode: boolean;
|
||||
}>`
|
||||
text-align: center;
|
||||
padding: 8px 0px;
|
||||
background-color: ${(props) =>
|
||||
props.darkMode
|
||||
? euiDarkVars.euiPageBackgroundColor
|
||||
: euiLightVars.euiPageBackgroundColor};
|
||||
border-bottom: 1px solid
|
||||
${(props) =>
|
||||
props.darkMode
|
||||
? euiDarkVars.euiColorLightestShade
|
||||
: euiLightVars.euiColorLightestShade};
|
||||
`;
|
||||
export type UrlOption<T = { [key: string]: any }> = {
|
||||
meta?: string[];
|
||||
isNewWildcard?: boolean;
|
||||
isWildcard?: boolean;
|
||||
title: string;
|
||||
} & EuiSelectableOption<T>;
|
||||
|
||||
interface Props {
|
||||
export interface SelectableUrlListProps {
|
||||
data: {
|
||||
items: UrlOption[];
|
||||
total?: number;
|
||||
};
|
||||
loading: boolean;
|
||||
onInputChange: (e: FormEvent<HTMLInputElement>) => void;
|
||||
onTermChange: () => void;
|
||||
onApply: () => void;
|
||||
onChange: (updatedOptions: UrlOption[]) => void;
|
||||
rowHeight?: number;
|
||||
onInputChange: (val: string) => void;
|
||||
onSelectionApply: () => void;
|
||||
onSelectionChange: (updatedOptions: UrlOption[]) => void;
|
||||
searchValue: string;
|
||||
popoverIsOpen: boolean;
|
||||
initialValue?: string;
|
||||
setPopoverIsOpen: React.Dispatch<SetStateAction<boolean>>;
|
||||
renderOption?: (option: UrlOption, searchValue: string) => ReactNode;
|
||||
hasChanged: () => boolean;
|
||||
}
|
||||
|
||||
export const formatOptions = (options: EuiSelectableOption[]) => {
|
||||
return options.map((item: EuiSelectableOption) => ({
|
||||
title: item.label,
|
||||
...item,
|
||||
className: classNames('euiSelectableTemplateSitewide__listItem', item.className),
|
||||
}));
|
||||
};
|
||||
export function SelectableUrlList({
|
||||
data,
|
||||
loading,
|
||||
onInputChange,
|
||||
onTermChange,
|
||||
onChange,
|
||||
onApply,
|
||||
onSelectionChange,
|
||||
onSelectionApply,
|
||||
searchValue,
|
||||
popoverIsOpen,
|
||||
setPopoverIsOpen,
|
||||
initialValue,
|
||||
}: Props) {
|
||||
const [darkMode] = useUiSetting$<boolean>('theme:darkMode');
|
||||
|
||||
renderOption,
|
||||
rowHeight,
|
||||
hasChanged,
|
||||
}: SelectableUrlListProps) {
|
||||
const [searchRef, setSearchRef] = useState<HTMLInputElement | null>(null);
|
||||
|
||||
const titleRef = useRef<HTMLDivElement>(null);
|
||||
|
@ -96,8 +85,7 @@ export function SelectableUrlList({
|
|||
|
||||
const onEnterKey = (evt: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (evt.key.toLowerCase() === 'enter') {
|
||||
onTermChange();
|
||||
onApply();
|
||||
onSelectionApply();
|
||||
setPopoverIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
@ -109,8 +97,8 @@ export function SelectableUrlList({
|
|||
}
|
||||
};
|
||||
|
||||
const onSearchInput = (e: React.FormEvent<HTMLInputElement>) => {
|
||||
onInputChange(e);
|
||||
const onSearchInput: FormEventHandler<HTMLInputElement> = (e) => {
|
||||
onInputChange((e.target as HTMLInputElement).value);
|
||||
setPopoverIsOpen(true);
|
||||
};
|
||||
|
||||
|
@ -123,14 +111,11 @@ export function SelectableUrlList({
|
|||
useEvent('escape', () => setPopoverIsOpen(false), searchRef);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchRef && initialValue) {
|
||||
searchRef.value = initialValue;
|
||||
if (searchRef && searchRef.value !== searchValue) {
|
||||
searchRef.value = searchValue;
|
||||
searchRef.dispatchEvent(new Event('change'));
|
||||
}
|
||||
|
||||
// only want to call it at initial render to set value
|
||||
// coming from initial value/url
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [searchRef]);
|
||||
}, [searchRef, searchValue]);
|
||||
|
||||
const loadingMessage = (
|
||||
<EuiSelectableMessage style={{ minHeight: 300 }}>
|
||||
|
@ -161,7 +146,7 @@ export function SelectableUrlList({
|
|||
<EuiButtonIcon
|
||||
color="text"
|
||||
onClick={() => closePopover()}
|
||||
aria-label={i18n.translate('xpack.apm.csm.search.url.close', {
|
||||
aria-label={i18n.translate('xpack.observability.search.url.close', {
|
||||
defaultMessage: 'Close',
|
||||
})}
|
||||
iconType={'cross'}
|
||||
|
@ -175,10 +160,9 @@ export function SelectableUrlList({
|
|||
return (
|
||||
<EuiSelectable
|
||||
searchable
|
||||
onChange={onChange}
|
||||
isLoading={loading}
|
||||
options={formattedOptions}
|
||||
renderOption={selectableRenderOptions}
|
||||
onChange={onSelectionChange}
|
||||
options={searchValue !== searchRef?.value ? [] : formattedOptions}
|
||||
renderOption={renderOption}
|
||||
singleSelection={false}
|
||||
searchProps={{
|
||||
isClearable: true,
|
||||
|
@ -189,7 +173,7 @@ export function SelectableUrlList({
|
|||
'aria-label': I18LABELS.filterByUrl,
|
||||
}}
|
||||
listProps={{
|
||||
rowHeight: 68,
|
||||
rowHeight,
|
||||
showIcons: true,
|
||||
onFocusBadge: false,
|
||||
}}
|
||||
|
@ -197,6 +181,7 @@ export function SelectableUrlList({
|
|||
emptyMessage={emptyMessage}
|
||||
noMatchesMessage={emptyMessage}
|
||||
allowExclusions={true}
|
||||
isPreFiltered={searchValue !== searchRef?.value}
|
||||
>
|
||||
{(list, search) => (
|
||||
<EuiPopover
|
||||
|
@ -216,24 +201,6 @@ export function SelectableUrlList({
|
|||
}}
|
||||
>
|
||||
<PopOverTitle />
|
||||
{searchValue && (
|
||||
<StyledRow darkMode={darkMode}>
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.apm.ux.url.hitEnter.include"
|
||||
defaultMessage="Hit {icon} or click apply to include all urls matching {searchValue}"
|
||||
values={{
|
||||
searchValue: <strong>{searchValue}</strong>,
|
||||
icon: (
|
||||
<EuiBadge color="hollow">
|
||||
Enter <EuiIcon type="returnKey" />
|
||||
</EuiBadge>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
</StyledRow>
|
||||
)}
|
||||
{list}
|
||||
<EuiPopoverFooter paddingSize="s">
|
||||
<EuiFlexGroup style={{ justifyContent: 'flex-end' }}>
|
||||
|
@ -242,12 +209,12 @@ export function SelectableUrlList({
|
|||
fill
|
||||
size="s"
|
||||
onClick={() => {
|
||||
onTermChange();
|
||||
onApply();
|
||||
onSelectionApply();
|
||||
closePopover();
|
||||
}}
|
||||
isDisabled={!hasChanged()}
|
||||
>
|
||||
{i18n.translate('xpack.apm.apply.label', {
|
||||
{i18n.translate('xpack.observability.apply.label', {
|
||||
defaultMessage: 'Apply',
|
||||
})}
|
||||
</EuiButton>
|
||||
|
@ -260,3 +227,6 @@ export function SelectableUrlList({
|
|||
</EuiSelectable>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default SelectableUrlList;
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const I18LABELS = {
|
||||
filterByUrl: i18n.translate('xpack.observability.filters.filterByUrl', {
|
||||
defaultMessage: 'Filter by URL',
|
||||
}),
|
||||
getSearchResultsLabel: (total: number) =>
|
||||
i18n.translate('xpack.observability.filters.searchResults', {
|
||||
defaultMessage: '{total} Search results',
|
||||
values: { total },
|
||||
}),
|
||||
topPages: i18n.translate('xpack.observability.filters.topPages', {
|
||||
defaultMessage: 'Top pages',
|
||||
}),
|
||||
select: i18n.translate('xpack.observability.filters.select', {
|
||||
defaultMessage: 'Select',
|
||||
}),
|
||||
url: i18n.translate('xpack.observability.filters.url', {
|
||||
defaultMessage: 'Url',
|
||||
}),
|
||||
loadingResults: i18n.translate('xpack.observability.filters.url.loadingResults', {
|
||||
defaultMessage: 'Loading results',
|
||||
}),
|
||||
noResults: i18n.translate('xpack.observability.filters.url.noResults', {
|
||||
defaultMessage: 'No results available',
|
||||
}),
|
||||
};
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { isEqual, map } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { SelectableUrlList, UrlOption } from './selectable_url_list';
|
||||
import { SeriesConfig, SeriesUrl, UrlFilter } from '../../types';
|
||||
import { useUrlSearch } from './use_url_search';
|
||||
import { useSeriesFilters } from '../../hooks/use_series_filters';
|
||||
import { TRANSACTION_URL } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
interface Props {
|
||||
seriesId: number;
|
||||
seriesConfig: SeriesConfig;
|
||||
series: SeriesUrl;
|
||||
}
|
||||
|
||||
const processSelectedItems = (items: UrlOption[]) => {
|
||||
const urlItems = items.filter(({ isWildcard }) => !isWildcard);
|
||||
|
||||
const wildcardItems = items.filter(({ isWildcard }) => isWildcard);
|
||||
|
||||
const includedItems = map(
|
||||
urlItems.filter((option) => option.checked === 'on'),
|
||||
'label'
|
||||
);
|
||||
|
||||
const excludedItems = map(
|
||||
urlItems.filter((option) => option.checked === 'off'),
|
||||
'label'
|
||||
);
|
||||
|
||||
// for wild cards we use title since label contains extra information
|
||||
const includedWildcards = map(
|
||||
wildcardItems.filter((option) => option.checked === 'on'),
|
||||
'title'
|
||||
);
|
||||
|
||||
// for wild cards we use title since label contains extra information
|
||||
const excludedWildcards = map(
|
||||
wildcardItems.filter((option) => option.checked === 'off'),
|
||||
'title'
|
||||
);
|
||||
|
||||
return { includedItems, excludedItems, includedWildcards, excludedWildcards };
|
||||
};
|
||||
|
||||
const getWildcardLabel = (wildcard: string) => {
|
||||
return i18n.translate('xpack.observability.urlFilter.wildcard', {
|
||||
defaultMessage: 'Use wildcard *{wildcard}*',
|
||||
values: { wildcard },
|
||||
});
|
||||
};
|
||||
|
||||
export function URLSearch({ series, seriesConfig, seriesId }: Props) {
|
||||
const [popoverIsOpen, setPopoverIsOpen] = useState(false);
|
||||
const [query, setQuery] = useState('');
|
||||
|
||||
const [items, setItems] = useState<UrlOption[]>([]);
|
||||
|
||||
const { values, loading } = useUrlSearch({
|
||||
query,
|
||||
series,
|
||||
seriesConfig,
|
||||
seriesId,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const queryLabel = getWildcardLabel(query);
|
||||
const currFilter: UrlFilter | undefined = (series.filters ?? []).find(
|
||||
({ field }) => field === TRANSACTION_URL
|
||||
);
|
||||
|
||||
const {
|
||||
wildcards = [],
|
||||
notWildcards = [],
|
||||
values: currValues = [],
|
||||
notValues: currNotValues = [],
|
||||
} = currFilter ?? { field: TRANSACTION_URL };
|
||||
|
||||
setItems((prevItems) => {
|
||||
const { includedItems, excludedItems } = processSelectedItems(prevItems);
|
||||
|
||||
const newItems: UrlOption[] = (values ?? []).map((item) => {
|
||||
if (
|
||||
includedItems.includes(item.label) ||
|
||||
wildcards.includes(item.label) ||
|
||||
currValues.includes(item.label)
|
||||
) {
|
||||
return { ...item, checked: 'on', title: item.label };
|
||||
}
|
||||
if (
|
||||
excludedItems.includes(item.label) ||
|
||||
notWildcards.includes(item.label) ||
|
||||
currNotValues.includes(item.label)
|
||||
) {
|
||||
return { ...item, checked: 'off', title: item.label, ...item };
|
||||
}
|
||||
return { ...item, title: item.label, checked: undefined };
|
||||
});
|
||||
|
||||
wildcards.forEach((wildcard) => {
|
||||
newItems.unshift({
|
||||
title: wildcard,
|
||||
label: getWildcardLabel(wildcard),
|
||||
isWildcard: true,
|
||||
checked: 'on',
|
||||
});
|
||||
});
|
||||
|
||||
notWildcards.forEach((wildcard) => {
|
||||
newItems.unshift({
|
||||
title: wildcard,
|
||||
label: getWildcardLabel(wildcard),
|
||||
isWildcard: true,
|
||||
checked: 'off',
|
||||
});
|
||||
});
|
||||
|
||||
let queryItem: UrlOption | undefined = prevItems.find(({ isNewWildcard }) => isNewWildcard);
|
||||
if (query) {
|
||||
if (!queryItem) {
|
||||
queryItem = {
|
||||
title: query,
|
||||
label: queryLabel,
|
||||
isNewWildcard: true,
|
||||
isWildcard: true,
|
||||
};
|
||||
newItems.unshift(queryItem);
|
||||
}
|
||||
|
||||
return [{ ...queryItem, label: queryLabel, title: query }, ...newItems];
|
||||
}
|
||||
|
||||
return newItems;
|
||||
});
|
||||
// we don't want to add series in the dependency, for that we have an extra side effect below
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [values, loading, query]);
|
||||
|
||||
useEffect(() => {
|
||||
const currFilter: UrlFilter | undefined = (series.filters ?? []).find(
|
||||
({ field }) => field === TRANSACTION_URL
|
||||
);
|
||||
|
||||
const {
|
||||
wildcards = [],
|
||||
notWildcards = [],
|
||||
values: currValues = [],
|
||||
notValues: currNotValues = [],
|
||||
} = currFilter ?? { field: TRANSACTION_URL };
|
||||
|
||||
setItems((prevItems) => {
|
||||
const newItems: UrlOption[] = (prevItems ?? []).map((item) => {
|
||||
if (currValues.includes(item.label) || wildcards.includes(item.title)) {
|
||||
return { ...item, checked: 'on' };
|
||||
}
|
||||
|
||||
if (currNotValues.includes(item.label) || notWildcards.includes(item.title)) {
|
||||
return { ...item, checked: 'off' };
|
||||
}
|
||||
return { ...item, checked: undefined };
|
||||
});
|
||||
|
||||
return newItems;
|
||||
});
|
||||
}, [series]);
|
||||
|
||||
const onSelectionChange = (updatedOptions: UrlOption[]) => {
|
||||
setItems(updatedOptions);
|
||||
};
|
||||
|
||||
const { replaceFilter } = useSeriesFilters({ seriesId, series });
|
||||
|
||||
const onSelectionApply = () => {
|
||||
const { includedItems, excludedItems, includedWildcards, excludedWildcards } =
|
||||
processSelectedItems(items);
|
||||
|
||||
replaceFilter({
|
||||
field: TRANSACTION_URL,
|
||||
values: includedItems,
|
||||
notValues: excludedItems,
|
||||
wildcards: includedWildcards,
|
||||
notWildcards: excludedWildcards,
|
||||
});
|
||||
|
||||
setQuery('');
|
||||
setPopoverIsOpen(false);
|
||||
};
|
||||
|
||||
const hasChanged = () => {
|
||||
const { includedItems, excludedItems, includedWildcards, excludedWildcards } =
|
||||
processSelectedItems(items);
|
||||
const currFilter: UrlFilter | undefined = (series.filters ?? []).find(
|
||||
({ field }) => field === TRANSACTION_URL
|
||||
);
|
||||
|
||||
const {
|
||||
wildcards = [],
|
||||
notWildcards = [],
|
||||
values: currValues = [],
|
||||
notValues: currNotValues = [],
|
||||
} = currFilter ?? { field: TRANSACTION_URL };
|
||||
|
||||
return (
|
||||
!isEqual(includedItems.sort(), currValues.sort()) ||
|
||||
!isEqual(excludedItems.sort(), currNotValues.sort()) ||
|
||||
!isEqual(wildcards.sort(), includedWildcards.sort()) ||
|
||||
!isEqual(notWildcards.sort(), excludedWildcards.sort())
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SelectableUrlList
|
||||
loading={Boolean(loading)}
|
||||
onInputChange={(val) => setQuery(val)}
|
||||
data={{ items, total: items.length }}
|
||||
onSelectionChange={onSelectionChange}
|
||||
searchValue={query}
|
||||
popoverIsOpen={popoverIsOpen}
|
||||
setPopoverIsOpen={setPopoverIsOpen}
|
||||
onSelectionApply={onSelectionApply}
|
||||
hasChanged={hasChanged}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SeriesConfig, SeriesUrl } from '../../types';
|
||||
import { TRANSACTION_URL } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
import { useFilterValues } from '../../series_editor/use_filter_values';
|
||||
|
||||
interface Props {
|
||||
query?: string;
|
||||
seriesId: number;
|
||||
series: SeriesUrl;
|
||||
seriesConfig: SeriesConfig;
|
||||
}
|
||||
export const useUrlSearch = ({ series, query, seriesId, seriesConfig }: Props) => {
|
||||
const { values, loading } = useFilterValues(
|
||||
{
|
||||
series,
|
||||
seriesId,
|
||||
field: TRANSACTION_URL,
|
||||
baseFilters: seriesConfig.baseFilters,
|
||||
label: seriesConfig.labels[TRANSACTION_URL],
|
||||
},
|
||||
query
|
||||
);
|
||||
|
||||
return { values, loading };
|
||||
};
|
|
@ -561,14 +561,14 @@ export class LensAttributes {
|
|||
}
|
||||
});
|
||||
|
||||
const rFilters = urlFiltersToKueryString(filters ?? []);
|
||||
const urlFilters = urlFiltersToKueryString(filters ?? []);
|
||||
if (!baseFilters) {
|
||||
return rFilters;
|
||||
return urlFilters;
|
||||
}
|
||||
if (!rFilters) {
|
||||
if (!urlFilters) {
|
||||
return baseFilters;
|
||||
}
|
||||
return `${rFilters} and ${baseFilters}`;
|
||||
return `${urlFilters} and ${baseFilters}`;
|
||||
}
|
||||
|
||||
getTimeShift(mainLayerConfig: LayerConfig, layerConfig: LayerConfig, index: number) {
|
||||
|
|
|
@ -64,10 +64,7 @@ export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): SeriesCon
|
|||
],
|
||||
hasOperationType: false,
|
||||
filterFields: [
|
||||
{
|
||||
field: TRANSACTION_URL,
|
||||
isNegated: false,
|
||||
},
|
||||
TRANSACTION_URL,
|
||||
USER_AGENT_OS,
|
||||
CLIENT_GEO_COUNTRY_NAME,
|
||||
USER_AGENT_DEVICE,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { concat } from 'lodash';
|
||||
import { useSeriesStorage } from './use_series_storage';
|
||||
import { SeriesUrl, UrlFilter } from '../types';
|
||||
|
||||
|
@ -12,6 +13,8 @@ export interface UpdateFilter {
|
|||
field: string;
|
||||
value: string | string[];
|
||||
negate?: boolean;
|
||||
wildcards?: string[];
|
||||
isWildcard?: boolean;
|
||||
}
|
||||
|
||||
export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; series: SeriesUrl }) => {
|
||||
|
@ -19,16 +22,60 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
|
||||
const filters = series.filters ?? [];
|
||||
|
||||
const removeFilter = ({ field, value, negate }: UpdateFilter) => {
|
||||
const replaceFilter = ({
|
||||
field,
|
||||
values,
|
||||
notValues,
|
||||
wildcards,
|
||||
notWildcards,
|
||||
}: {
|
||||
field: string;
|
||||
values: string[];
|
||||
notValues: string[];
|
||||
wildcards?: string[];
|
||||
notWildcards?: string[];
|
||||
}) => {
|
||||
const currFilter: UrlFilter | undefined = filters.find(({ field: fd }) => field === fd) ?? {
|
||||
field,
|
||||
};
|
||||
|
||||
currFilter.notValues = notValues.length > 0 ? notValues : undefined;
|
||||
currFilter.values = values.length > 0 ? values : undefined;
|
||||
|
||||
currFilter.wildcards = wildcards;
|
||||
currFilter.notWildcards = notWildcards;
|
||||
|
||||
const otherFilters = filters.filter(({ field: fd }) => fd !== field);
|
||||
|
||||
if (concat(values, notValues, wildcards, notWildcards).length > 0) {
|
||||
setSeries(seriesId, { ...series, filters: [...otherFilters, currFilter] });
|
||||
} else {
|
||||
setSeries(seriesId, { ...series, filters: otherFilters });
|
||||
}
|
||||
};
|
||||
|
||||
const removeFilter = ({ field, value, negate, isWildcard }: UpdateFilter) => {
|
||||
const filtersN = filters
|
||||
.map((filter) => {
|
||||
if (filter.field === field) {
|
||||
if (negate) {
|
||||
if (isWildcard) {
|
||||
const notWildcardsN = filter.notWildcards?.filter((val) =>
|
||||
value instanceof Array ? !value.includes(val) : val !== value
|
||||
);
|
||||
return { ...filter, notWildcards: notWildcardsN };
|
||||
}
|
||||
const notValuesN = filter.notValues?.filter((val) =>
|
||||
value instanceof Array ? !value.includes(val) : val !== value
|
||||
);
|
||||
return { ...filter, notValues: notValuesN };
|
||||
} else {
|
||||
if (isWildcard) {
|
||||
const wildcardsN = filter.wildcards?.filter((val) =>
|
||||
value instanceof Array ? !value.includes(val) : val !== value
|
||||
);
|
||||
return { ...filter, wildcards: wildcardsN };
|
||||
}
|
||||
const valuesN = filter.values?.filter((val) =>
|
||||
value instanceof Array ? !value.includes(val) : val !== value
|
||||
);
|
||||
|
@ -38,7 +85,13 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
|
||||
return filter;
|
||||
})
|
||||
.filter(({ values = [], notValues = [] }) => values.length > 0 || notValues.length > 0);
|
||||
.filter(
|
||||
({ values = [], notValues = [], wildcards = [], notWildcards = [] }) =>
|
||||
values.length > 0 ||
|
||||
notValues.length > 0 ||
|
||||
wildcards.length > 0 ||
|
||||
notWildcards.length > 0
|
||||
);
|
||||
setSeries(seriesId, { ...series, filters: filtersN });
|
||||
};
|
||||
|
||||
|
@ -49,6 +102,7 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
} else {
|
||||
currFilter.values = value instanceof Array ? value : [value];
|
||||
}
|
||||
|
||||
if (filters.length === 0) {
|
||||
setSeries(seriesId, { ...series, filters: [currFilter] });
|
||||
} else {
|
||||
|
@ -59,7 +113,7 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
}
|
||||
};
|
||||
|
||||
const updateFilter = ({ field, value, negate }: UpdateFilter) => {
|
||||
const updateFilter = ({ field, value, negate, wildcards }: UpdateFilter) => {
|
||||
const currFilter: UrlFilter | undefined = filters.find(({ field: fd }) => field === fd) ?? {
|
||||
field,
|
||||
};
|
||||
|
@ -89,25 +143,40 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
}
|
||||
}
|
||||
|
||||
currFilter.notValues = notValues.length > 0 ? notValues : undefined;
|
||||
currFilter.values = values.length > 0 ? values : undefined;
|
||||
|
||||
const otherFilters = filters.filter(({ field: fd }) => fd !== field);
|
||||
|
||||
if (notValues.length > 0 || values.length > 0) {
|
||||
setSeries(seriesId, { ...series, filters: [...otherFilters, currFilter] });
|
||||
} else {
|
||||
setSeries(seriesId, { ...series, filters: otherFilters });
|
||||
}
|
||||
replaceFilter({ field, values, notValues, wildcards });
|
||||
};
|
||||
|
||||
const setFilter = ({ field, value, negate }: UpdateFilter) => {
|
||||
const setFilter = ({ field, value, negate, wildcards }: UpdateFilter) => {
|
||||
const currFilter: UrlFilter | undefined = filters.find(({ field: fd }) => field === fd);
|
||||
|
||||
if (!currFilter) {
|
||||
addFilter({ field, value, negate });
|
||||
addFilter({ field, value, negate, wildcards });
|
||||
} else {
|
||||
updateFilter({ field, value, negate });
|
||||
updateFilter({ field, value, negate, wildcards });
|
||||
}
|
||||
};
|
||||
|
||||
const setFiltersWildcard = ({ field, wildcards }: { field: string; wildcards: string[] }) => {
|
||||
let currFilter: UrlFilter | undefined = filters.find(({ field: fd }) => field === fd);
|
||||
|
||||
if (!currFilter) {
|
||||
currFilter = { field, wildcards };
|
||||
|
||||
if (filters.length === 0) {
|
||||
setSeries(seriesId, { ...series, filters: [currFilter] });
|
||||
} else {
|
||||
setSeries(seriesId, {
|
||||
...series,
|
||||
filters: [currFilter, ...filters.filter((ft) => ft.field !== field)],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
replaceFilter({
|
||||
field,
|
||||
values: currFilter.values ?? [],
|
||||
notValues: currFilter.notValues ?? [],
|
||||
wildcards,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -115,5 +184,5 @@ export const useSeriesFilters = ({ seriesId, series }: { seriesId: number; serie
|
|||
updateFilter({ field, value, negate: !negate });
|
||||
};
|
||||
|
||||
return { invertFilter, setFilter, removeFilter };
|
||||
return { invertFilter, setFilter, removeFilter, replaceFilter, setFiltersWildcard };
|
||||
};
|
||||
|
|
|
@ -307,10 +307,14 @@ export function mockUseSeriesFilter() {
|
|||
const removeFilter = jest.fn();
|
||||
const invertFilter = jest.fn();
|
||||
const setFilter = jest.fn();
|
||||
const replaceFilter = jest.fn();
|
||||
const setFiltersWildcard = jest.fn();
|
||||
const spy = jest.spyOn(useSeriesFilterHook, 'useSeriesFilters').mockReturnValue({
|
||||
removeFilter,
|
||||
invertFilter,
|
||||
setFilter,
|
||||
replaceFilter,
|
||||
setFiltersWildcard,
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -318,6 +322,8 @@ export function mockUseSeriesFilter() {
|
|||
removeFilter,
|
||||
invertFilter,
|
||||
setFilter,
|
||||
replaceFilter,
|
||||
setFiltersWildcard,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export function SelectedFilters({ seriesId, series, seriesConfig }: Props) {
|
|||
|
||||
const filters: UrlFilter[] = series.filters ?? [];
|
||||
|
||||
const { removeFilter } = useSeriesFilters({ seriesId, series });
|
||||
const { removeFilter, replaceFilter } = useSeriesFilters({ seriesId, series });
|
||||
|
||||
const { indexPattern } = useAppIndexPatternContext(series.dataType);
|
||||
|
||||
|
@ -34,49 +34,99 @@ export function SelectedFilters({ seriesId, series, seriesConfig }: Props) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const btnProps = {
|
||||
seriesId,
|
||||
series,
|
||||
indexPattern,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup wrap gutterSize="xs">
|
||||
{filters.map(({ field, values, notValues }) => (
|
||||
<Fragment key={field}>
|
||||
{(values ?? []).length > 0 && (
|
||||
<EuiFlexItem grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
seriesId={seriesId}
|
||||
series={series}
|
||||
field={field}
|
||||
label={labels[field] ?? field}
|
||||
value={values ?? []}
|
||||
removeFilter={() => {
|
||||
values?.forEach((val) => {
|
||||
removeFilter({ field, value: val, negate: false });
|
||||
});
|
||||
}}
|
||||
negate={false}
|
||||
indexPattern={indexPattern}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{(notValues ?? []).length > 0 && (
|
||||
<EuiFlexItem key={field} grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
series={series}
|
||||
seriesId={seriesId}
|
||||
field={field}
|
||||
label={labels[field] ?? field}
|
||||
value={notValues ?? []}
|
||||
negate={true}
|
||||
removeFilter={() => {
|
||||
values?.forEach((val) => {
|
||||
removeFilter({ field, value: val, negate: false });
|
||||
});
|
||||
}}
|
||||
indexPattern={indexPattern}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
<EuiFlexGroup wrap gutterSize="xs" alignItems="center">
|
||||
{filters.map(
|
||||
({ field, values = [], notValues = [], wildcards = [], notWildcards = [] }) => (
|
||||
<Fragment key={field}>
|
||||
{values.length > 0 && (
|
||||
<EuiFlexItem grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
field={field}
|
||||
label={labels[field] ?? field}
|
||||
value={values ?? []}
|
||||
removeFilter={() => {
|
||||
replaceFilter({
|
||||
field,
|
||||
values: [],
|
||||
notValues,
|
||||
wildcards,
|
||||
notWildcards,
|
||||
});
|
||||
}}
|
||||
negate={false}
|
||||
{...btnProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{notValues.length > 0 && (
|
||||
<EuiFlexItem key={field} grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
field={field}
|
||||
label={labels[field] ?? field}
|
||||
value={notValues ?? []}
|
||||
negate={true}
|
||||
removeFilter={() => {
|
||||
replaceFilter({
|
||||
field,
|
||||
notValues: [],
|
||||
values,
|
||||
wildcards,
|
||||
notWildcards,
|
||||
});
|
||||
}}
|
||||
{...btnProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{wildcards.length > 0 && (
|
||||
<EuiFlexItem key={field} grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
field={field}
|
||||
label={i18n.translate('xpack.observability.filters.label.wildcard', {
|
||||
defaultMessage: '{label} wildcard',
|
||||
values: { label: labels[field] ?? field },
|
||||
})}
|
||||
value={wildcards ?? []}
|
||||
negate={false}
|
||||
removeFilter={() => {
|
||||
wildcards?.forEach((val) => {
|
||||
removeFilter({ field, value: val, negate: false, isWildcard: true });
|
||||
});
|
||||
}}
|
||||
{...btnProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{notWildcards.length > 0 && (
|
||||
<EuiFlexItem key={field} grow={false} style={{ maxWidth: 300 }}>
|
||||
<FilterLabel
|
||||
field={field}
|
||||
label={i18n.translate('xpack.observability.filters.label.wildcard', {
|
||||
defaultMessage: '{label} wildcard',
|
||||
values: { label: labels[field] ?? field },
|
||||
})}
|
||||
value={notWildcards ?? []}
|
||||
negate={false}
|
||||
removeFilter={() => {
|
||||
notWildcards?.forEach((val) => {
|
||||
removeFilter({ field, value: val, negate: true, isWildcard: true });
|
||||
});
|
||||
}}
|
||||
{...btnProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</Fragment>
|
||||
)
|
||||
)}
|
||||
|
||||
{(series.filters ?? []).length > 0 && (
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiFilterGroup, EuiSpacer } from '@elastic/eui';
|
||||
import { EuiFilterGroup, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { FilterExpanded } from './filter_expanded';
|
||||
import { SeriesConfig, SeriesUrl } from '../../types';
|
||||
import { FieldLabels, LABEL_FIELDS_FILTER } from '../../configurations/constants/constants';
|
||||
import { SelectedFilters } from './selected_filters';
|
||||
import { LabelsFieldFilter } from '../components/labels_filter';
|
||||
import { URLSearch } from '../../components/url_search/url_search';
|
||||
import { TRANSACTION_URL } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
interface Props {
|
||||
seriesId: number;
|
||||
|
@ -27,42 +29,52 @@ export interface Field {
|
|||
}
|
||||
|
||||
export function SeriesFilter({ series, seriesConfig, seriesId }: Props) {
|
||||
const options: Field[] = seriesConfig.filterFields.map((field) => {
|
||||
if (typeof field === 'string') {
|
||||
return { label: seriesConfig.labels?.[field] ?? FieldLabels[field], field };
|
||||
}
|
||||
const options: Field[] = seriesConfig.filterFields
|
||||
.filter((field) => field !== TRANSACTION_URL)
|
||||
.map((field) => {
|
||||
if (typeof field === 'string') {
|
||||
return { label: seriesConfig.labels?.[field] ?? FieldLabels[field], field };
|
||||
}
|
||||
|
||||
return {
|
||||
field: field.field,
|
||||
nestedField: field.nested,
|
||||
isNegated: field.isNegated,
|
||||
label: seriesConfig.labels?.[field.field] ?? FieldLabels[field.field],
|
||||
};
|
||||
});
|
||||
return {
|
||||
field: field.field,
|
||||
nestedField: field.nested,
|
||||
isNegated: field.isNegated,
|
||||
label: seriesConfig.labels?.[field.field] ?? FieldLabels[field.field],
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFilterGroup>
|
||||
{options.map((opt) =>
|
||||
opt.field === LABEL_FIELDS_FILTER ? (
|
||||
<LabelsFieldFilter
|
||||
series={series}
|
||||
key={opt.label}
|
||||
seriesId={seriesId}
|
||||
baseFilters={seriesConfig.baseFilters}
|
||||
{...opt}
|
||||
/>
|
||||
) : (
|
||||
<FilterExpanded
|
||||
series={series}
|
||||
key={opt.label}
|
||||
seriesId={seriesId}
|
||||
baseFilters={seriesConfig.baseFilters}
|
||||
{...opt}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</EuiFilterGroup>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<URLSearch series={series} seriesId={seriesId} seriesConfig={seriesConfig} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFilterGroup>
|
||||
{options.map((opt) =>
|
||||
opt.field === LABEL_FIELDS_FILTER ? (
|
||||
<LabelsFieldFilter
|
||||
series={series}
|
||||
key={opt.label}
|
||||
seriesId={seriesId}
|
||||
baseFilters={seriesConfig.baseFilters}
|
||||
{...opt}
|
||||
/>
|
||||
) : (
|
||||
<FilterExpanded
|
||||
series={series}
|
||||
key={opt.label}
|
||||
seriesId={seriesId}
|
||||
baseFilters={seriesConfig.baseFilters}
|
||||
{...opt}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</EuiFilterGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
<SelectedFilters seriesId={seriesId} series={series} seriesConfig={seriesConfig} />
|
||||
</>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern';
|
|||
import { ESFilter } from '../../../../../../../../src/core/types/elasticsearch';
|
||||
import { PersistableFilter } from '../../../../../../lens/common';
|
||||
|
||||
export function useFilterValues({ field, series, baseFilters }: FilterProps, query: string) {
|
||||
export function useFilterValues({ field, series, baseFilters }: FilterProps, query?: string) {
|
||||
const { indexPatterns } = useAppIndexPatternContext(series.dataType);
|
||||
|
||||
const queryFilters: ESFilter[] = [];
|
||||
|
|
|
@ -89,6 +89,8 @@ export interface UrlFilter {
|
|||
field: string;
|
||||
values?: string[];
|
||||
notValues?: string[];
|
||||
wildcards?: string[];
|
||||
notWildcards?: string[];
|
||||
}
|
||||
|
||||
export interface ConfigProps {
|
||||
|
|
|
@ -36,7 +36,7 @@ describe('stringifyKueries', () => {
|
|||
},
|
||||
];
|
||||
expect(urlFiltersToKueryString(filters)).toMatchInlineSnapshot(
|
||||
`"user_agent.name: (\\"Chrome\\")"`
|
||||
`"user_agent.name: \\"Chrome\\""`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -64,7 +64,7 @@ describe('stringifyKueries', () => {
|
|||
},
|
||||
];
|
||||
expect(urlFiltersToKueryString(filters)).toMatchInlineSnapshot(
|
||||
`"user_agent.name: (\\"Google Chrome\\")"`
|
||||
`"user_agent.name: \\"Google Chrome\\""`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -77,7 +77,7 @@ describe('stringifyKueries', () => {
|
|||
},
|
||||
];
|
||||
expect(urlFiltersToKueryString(filters)).toMatchInlineSnapshot(
|
||||
`"user_agent.name: (\\"Google Chrome\\") and not (user_agent.name: (\\"Apple Safari\\"))"`
|
||||
`"user_agent.name: \\"Google Chrome\\" and not (user_agent.name: \\"Apple Safari\\")"`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -90,7 +90,7 @@ describe('stringifyKueries', () => {
|
|||
},
|
||||
];
|
||||
expect(urlFiltersToKueryString(filters)).toMatchInlineSnapshot(
|
||||
`"user_agent.name: (\\"Chrome\\" or \\"Firefox\\" or \\"Safari\\" or \\"Opera\\") and not (user_agent.name: (\\"Safari\\"))"`
|
||||
`"user_agent.name: (\\"Chrome\\" or \\"Firefox\\" or \\"Safari\\" or \\"Opera\\") and not (user_agent.name: \\"Safari\\")"`
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -12,24 +12,45 @@ import { UrlFilter } from '../types';
|
|||
* The strings contain all of the values chosen for the given field (which is also the key value).
|
||||
* Reduce the list of query strings to a singular string, with AND operators between.
|
||||
*/
|
||||
|
||||
const buildOrCondition = (values: string[]) => {
|
||||
if (values.length === 1) {
|
||||
return `${values.join(' or ')}`;
|
||||
}
|
||||
return `(${values.join(' or ')})`;
|
||||
};
|
||||
export const urlFiltersToKueryString = (urlFilters: UrlFilter[]): string => {
|
||||
let kueryString = '';
|
||||
urlFilters.forEach(({ field, values, notValues }) => {
|
||||
urlFilters.forEach(({ field, values, notValues, wildcards, notWildcards }) => {
|
||||
const valuesT = values?.map((val) => `"${val}"`);
|
||||
const notValuesT = notValues?.map((val) => `"${val}"`);
|
||||
const wildcardsT = wildcards?.map((val) => `*${val}*`);
|
||||
const notWildcardsT = notWildcards?.map((val) => `*${val}*`);
|
||||
|
||||
if (valuesT && valuesT?.length > 0) {
|
||||
if (kueryString.length > 0) {
|
||||
kueryString += ' and ';
|
||||
}
|
||||
kueryString += `${field}: (${valuesT.join(' or ')})`;
|
||||
kueryString += `${field}: ${buildOrCondition(valuesT)}`;
|
||||
}
|
||||
|
||||
if (notValuesT && notValuesT?.length > 0) {
|
||||
if (kueryString.length > 0) {
|
||||
kueryString += ' and ';
|
||||
}
|
||||
kueryString += `not (${field}: (${notValuesT.join(' or ')}))`;
|
||||
kueryString += `not (${field}: ${buildOrCondition(notValuesT)})`;
|
||||
}
|
||||
if (wildcardsT && wildcardsT?.length > 0) {
|
||||
if (kueryString.length > 0) {
|
||||
kueryString += ' and ';
|
||||
}
|
||||
kueryString += `(${field}: ${buildOrCondition(wildcardsT)})`;
|
||||
}
|
||||
if (notWildcardsT && notWildcardsT?.length > 0) {
|
||||
if (kueryString.length > 0) {
|
||||
kueryString += ' and ';
|
||||
}
|
||||
kueryString += `(${field}: ${buildOrCondition(notWildcardsT)})`;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import { EuiLoadingSpinner } from '@elastic/eui';
|
|||
import type { CoreVitalProps, HeaderMenuPortalProps } from './types';
|
||||
import type { FieldValueSuggestionsProps } from './field_value_suggestions/types';
|
||||
import type { FilterValueLabelProps } from './filter_value_label/filter_value_label';
|
||||
import type { SelectableUrlListProps } from './exploratory_view/components/url_search/selectable_url_list';
|
||||
|
||||
export { createLazyObservabilityPageTemplate } from './page_template';
|
||||
export type { LazyObservabilityPageTemplateProps } from './page_template';
|
||||
|
@ -53,3 +54,15 @@ export function FilterValueLabel(props: FilterValueLabelProps) {
|
|||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const SelectableUrlListLazy = lazy(
|
||||
() => import('./exploratory_view/components/url_search/selectable_url_list')
|
||||
);
|
||||
|
||||
export function SelectableUrlList(props: SelectableUrlListProps) {
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<SelectableUrlListLazy {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { useEffect, useState } from 'react';
|
|||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { ESFilter } from '../../../../../src/core/types/elasticsearch';
|
||||
import { createEsParams, useEsSearch } from './use_es_search';
|
||||
import { TRANSACTION_URL } from '../components/shared/exploratory_view/configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
export interface Props {
|
||||
sourceField: string;
|
||||
|
@ -30,6 +31,29 @@ const uniqueValues = (values: ListItem[], prevValues: ListItem[]) => {
|
|||
return uniqBy([...values, ...prevValues], 'label');
|
||||
};
|
||||
|
||||
const getIncludeClause = (sourceField: string, query?: string) => {
|
||||
if (!query) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let includeClause = '';
|
||||
|
||||
if (sourceField === TRANSACTION_URL) {
|
||||
// for the url we also match leading text
|
||||
includeClause = `*.${query.toLowerCase()}.*`;
|
||||
} else {
|
||||
if (query[0].toLowerCase() === query[0]) {
|
||||
// if first letter is lowercase we also add the capitalize option
|
||||
includeClause = `(${query}|${capitalize(query)}).*`;
|
||||
} else {
|
||||
// otherwise we add lowercase option prefix
|
||||
includeClause = `(${query}|${query.toLowerCase()}).*`;
|
||||
}
|
||||
}
|
||||
|
||||
return includeClause;
|
||||
};
|
||||
|
||||
export const useValuesList = ({
|
||||
sourceField,
|
||||
indexPatternTitle,
|
||||
|
@ -44,18 +68,6 @@ export const useValuesList = ({
|
|||
|
||||
const { from, to } = time ?? {};
|
||||
|
||||
let includeClause = '';
|
||||
|
||||
if (query) {
|
||||
if (query[0].toLowerCase() === query[0]) {
|
||||
// if first letter is lowercase we also add the capitalize option
|
||||
includeClause = `(${query}|${capitalize(query)}).*`;
|
||||
} else {
|
||||
// otherwise we add lowercase option prefix
|
||||
includeClause = `(${query}|${query.toLowerCase()}).*`;
|
||||
}
|
||||
}
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
setDebounceQuery(query);
|
||||
|
@ -71,6 +83,8 @@ export const useValuesList = ({
|
|||
}
|
||||
}, [query]);
|
||||
|
||||
const includeClause = getIncludeClause(sourceField, query);
|
||||
|
||||
const { data, loading } = useEsSearch(
|
||||
createEsParams({
|
||||
index: indexPatternTitle!,
|
||||
|
|
|
@ -46,6 +46,7 @@ export {
|
|||
HeaderMenuPortal,
|
||||
FieldValueSuggestions,
|
||||
FilterValueLabel,
|
||||
SelectableUrlList,
|
||||
} from './components/shared/';
|
||||
|
||||
export type { LazyObservabilityPageTemplateProps } from './components/shared';
|
||||
|
|
|
@ -6225,7 +6225,6 @@
|
|||
"xpack.apm.apmDescription": "アプリケーション内から自動的に詳細なパフォーマンスメトリックやエラーを集めます。",
|
||||
"xpack.apm.apmSchema.index": "APMサーバースキーマ - インデックス",
|
||||
"xpack.apm.apmSettings.index": "APM 設定 - インデックス",
|
||||
"xpack.apm.apply.label": "適用",
|
||||
"xpack.apm.backendDetail.dependenciesTableColumnBackend": "サービス",
|
||||
"xpack.apm.backendDetail.dependenciesTableTitle": "アップストリームサービス",
|
||||
"xpack.apm.backendDetailFailedTransactionRateChartTitle": "失敗したトランザクション率",
|
||||
|
@ -6288,7 +6287,6 @@
|
|||
"xpack.apm.csm.breakDownFilter.noBreakdown": "内訳なし",
|
||||
"xpack.apm.csm.breakdownFilter.os": "OS",
|
||||
"xpack.apm.csm.pageViews.analyze": "分析",
|
||||
"xpack.apm.csm.search.url.close": "閉じる",
|
||||
"xpack.apm.customLink.buttom.create": "カスタムリンクを作成",
|
||||
"xpack.apm.customLink.buttom.create.title": "作成",
|
||||
"xpack.apm.customLink.buttom.manage": "カスタムリンクを管理",
|
||||
|
@ -6491,13 +6489,6 @@
|
|||
"xpack.apm.rum.filterGroup.coreWebVitals": "コアWebバイタル",
|
||||
"xpack.apm.rum.filterGroup.seconds": "秒",
|
||||
"xpack.apm.rum.filterGroup.selectBreakdown": "内訳を選択",
|
||||
"xpack.apm.rum.filters.filterByUrl": "IDでフィルタリング",
|
||||
"xpack.apm.rum.filters.searchResults": "{total}件の検索結果",
|
||||
"xpack.apm.rum.filters.select": "選択してください",
|
||||
"xpack.apm.rum.filters.topPages": "上位のページ",
|
||||
"xpack.apm.rum.filters.url": "Url",
|
||||
"xpack.apm.rum.filters.url.loadingResults": "結果を読み込み中",
|
||||
"xpack.apm.rum.filters.url.noResults": "結果がありません",
|
||||
"xpack.apm.rum.jsErrors.errorMessage": "エラーメッセージ",
|
||||
"xpack.apm.rum.jsErrors.errorRate": "エラー率",
|
||||
"xpack.apm.rum.jsErrors.impactedPageLoads": "影響を受けるページ読み込み数",
|
||||
|
@ -7030,7 +7021,6 @@
|
|||
"xpack.apm.ux.percentile.label": "パーセンタイル",
|
||||
"xpack.apm.ux.percentiles.label": "{value} パーセンタイル",
|
||||
"xpack.apm.ux.title": "ダッシュボード",
|
||||
"xpack.apm.ux.url.hitEnter.include": "{icon} をクリックするか、[適用]をクリックすると、{searchValue} と一致するすべての URL が含まれます",
|
||||
"xpack.apm.ux.visitorBreakdown.noData": "データがありません。",
|
||||
"xpack.apm.views.dependencies.title": "依存関係",
|
||||
"xpack.apm.views.errors.title": "エラー",
|
||||
|
@ -7052,6 +7042,295 @@
|
|||
"xpack.apm.views.traceOverview.title": "トレース",
|
||||
"xpack.apm.views.transactions.title": "トランザクション",
|
||||
"xpack.apm.waterfall.exceedsMax": "このトレースの項目数は表示されている範囲を超えています",
|
||||
"xpack.observability.apply.label": "適用",
|
||||
"xpack.observability.search.url.close": "閉じる",
|
||||
"xpack.observability.filters.filterByUrl": "IDでフィルタリング",
|
||||
"xpack.observability.filters.searchResults": "{total}件の検索結果",
|
||||
"xpack.observability.filters.select": "選択してください",
|
||||
"xpack.observability.filters.topPages": "上位のページ",
|
||||
"xpack.observability.filters.url": "Url",
|
||||
"xpack.observability.filters.url.loadingResults": "結果を読み込み中",
|
||||
"xpack.observability.filters.url.noResults": "結果がありません",
|
||||
"xpack.observability.alerts.manageRulesButtonLabel": "ルールの管理",
|
||||
"xpack.observability.alerts.searchBarPlaceholder": "kibana.alert.evaluation.threshold > 75",
|
||||
"xpack.observability.alertsDisclaimerLinkText": "アラートとアクション",
|
||||
"xpack.observability.alertsDisclaimerText": "このページには実験アラートビューが表示されます。ここに表示されるデータは、アラートを正確に表していない可能性があります。アラートの非実験リストは、スタック管理のアラートとアクション設定にあります。",
|
||||
"xpack.observability.alertsDisclaimerTitle": "実験的",
|
||||
"xpack.observability.alertsFlyout.actualValueLabel": "実際の値",
|
||||
"xpack.observability.alertsFlyout.durationLabel": "期間",
|
||||
"xpack.observability.alertsFlyout.expectedValueLabel": "想定された値",
|
||||
"xpack.observability.alertsFlyout.ruleTypeLabel": "ルールタイプ",
|
||||
"xpack.observability.alertsFlyout.statusLabel": "ステータス",
|
||||
"xpack.observability.alertsLinkTitle": "アラート",
|
||||
"xpack.observability.alertsTable.actionsTextLabel": "アクション",
|
||||
"xpack.observability.alertsTable.footerTextLabel": "アラート",
|
||||
"xpack.observability.alertsTable.loadingTextLabel": "アラートを読み込んでいます",
|
||||
"xpack.observability.alertsTGrid.durationColumnDescription": "期間",
|
||||
"xpack.observability.alertsTGrid.lastUpdatedColumnDescription": "最終更新",
|
||||
"xpack.observability.alertsTGrid.reasonColumnDescription": "理由",
|
||||
"xpack.observability.alertsTGrid.statusColumnDescription": "ステータス",
|
||||
"xpack.observability.alertsTitle": "アラート",
|
||||
"xpack.observability.breadcrumbs.alertsLinkText": "アラート",
|
||||
"xpack.observability.breadcrumbs.casesConfigureLinkText": "構成",
|
||||
"xpack.observability.breadcrumbs.casesCreateLinkText": "作成",
|
||||
"xpack.observability.breadcrumbs.casesLinkText": "ケース",
|
||||
"xpack.observability.breadcrumbs.landingLinkText": "はじめて使う",
|
||||
"xpack.observability.breadcrumbs.observabilityLinkText": "オブザーバビリティ",
|
||||
"xpack.observability.breadcrumbs.overviewLinkText": "概要",
|
||||
"xpack.observability.cases.allCases.actions": "アクション",
|
||||
"xpack.observability.cases.allCases.comments": "コメント",
|
||||
"xpack.observability.cases.allCases.noTagsAvailable": "利用可能なタグがありません",
|
||||
"xpack.observability.cases.badge.readOnly.text": "読み取り専用",
|
||||
"xpack.observability.cases.badge.readOnly.tooltip": "ケースを作成または編集できません",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsMessage": "ケースを表示するには、Kibana スペースでケース機能の権限が必要です。詳細については、Kibana管理者に連絡してください。",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsTitle": "Kibana機能権限が必要です",
|
||||
"xpack.observability.cases.caseView.backLabel": "ケースに戻る",
|
||||
"xpack.observability.cases.caseView.cancel": "キャンセル",
|
||||
"xpack.observability.cases.caseView.caseName": "ケース名",
|
||||
"xpack.observability.cases.caseView.closeCase": "ケースを閉じる",
|
||||
"xpack.observability.cases.caseView.comment.addComment": "コメントを追加",
|
||||
"xpack.observability.cases.caseView.comment.addCommentHelpText": "新しいコメントを追加...",
|
||||
"xpack.observability.cases.caseView.commentFieldRequiredError": "コメントが必要です。",
|
||||
"xpack.observability.cases.caseView.connectors": "外部インシデント管理システム",
|
||||
"xpack.observability.cases.caseView.create": "新規ケースを作成",
|
||||
"xpack.observability.cases.caseView.createCase": "ケースを作成",
|
||||
"xpack.observability.cases.caseView.description": "説明",
|
||||
"xpack.observability.cases.caseView.description.save": "保存",
|
||||
"xpack.observability.cases.caseView.edit": "編集",
|
||||
"xpack.observability.cases.caseView.editConnector": "外部インシデント管理システムを変更",
|
||||
"xpack.observability.cases.caseView.fieldRequiredError": "必須フィールド",
|
||||
"xpack.observability.cases.caseView.goToDocumentationButton": "ドキュメンテーションを表示",
|
||||
"xpack.observability.cases.caseView.name": "名前",
|
||||
"xpack.observability.cases.caseView.noReportersAvailable": "利用可能なレポートがありません。",
|
||||
"xpack.observability.cases.caseView.noTags": "現在、このケースにタグは割り当てられていません。",
|
||||
"xpack.observability.cases.caseView.optional": "オプション",
|
||||
"xpack.observability.cases.caseView.particpantsLabel": "参加者",
|
||||
"xpack.observability.cases.caseView.reopenCase": "ケースを再開",
|
||||
"xpack.observability.cases.caseView.reporterLabel": "報告者",
|
||||
"xpack.observability.cases.caseView.tags": "タグ",
|
||||
"xpack.observability.cases.caseView.to": "に",
|
||||
"xpack.observability.cases.configureCases.headerTitle": "ケースを構成",
|
||||
"xpack.observability.cases.configureCasesButton": "外部接続を編集",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCase": "ケースを削除",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCases": "ケースを削除",
|
||||
"xpack.observability.cases.createCase.descriptionFieldRequiredError": "説明が必要です。",
|
||||
"xpack.observability.cases.createCase.fieldTagsHelpText": "このケースの1つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。",
|
||||
"xpack.observability.cases.createCase.titleFieldRequiredError": "タイトルが必要です。",
|
||||
"xpack.observability.cases.dismissErrorsPushServiceCallOutTitle": "閉じる",
|
||||
"xpack.observability.cases.pageTitle": "ケース",
|
||||
"xpack.observability.casesLinkTitle": "ケース",
|
||||
"xpack.observability.emptySection.apps.alert.description": "503 エラーが累積していますか?サービスは応答していますか?CPUとRAMの使用量が跳ね上がっていますか?このような警告を、事後にではなく、発生と同時に把握しましょう。",
|
||||
"xpack.observability.emptySection.apps.alert.link": "ルールを作成",
|
||||
"xpack.observability.emptySection.apps.alert.title": "アラートが見つかりません。",
|
||||
"xpack.observability.emptySection.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。",
|
||||
"xpack.observability.emptySection.apps.apm.link": "エージェントのインストール",
|
||||
"xpack.observability.emptySection.apps.apm.title": "APM",
|
||||
"xpack.observability.emptySection.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。",
|
||||
"xpack.observability.emptySection.apps.logs.link": "Filebeatをインストール",
|
||||
"xpack.observability.emptySection.apps.logs.title": "ログ",
|
||||
"xpack.observability.emptySection.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。",
|
||||
"xpack.observability.emptySection.apps.metrics.link": "Metricbeatのインストール",
|
||||
"xpack.observability.emptySection.apps.metrics.title": "メトリック",
|
||||
"xpack.observability.emptySection.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。",
|
||||
"xpack.observability.emptySection.apps.uptime.link": "Heartbeatのインストール",
|
||||
"xpack.observability.emptySection.apps.uptime.title": "アップタイム",
|
||||
"xpack.observability.emptySection.apps.ux.description": "パフォーマンスは分散です。Web アプリケーションにアクセスするすべてのユーザーの経験を計測し、全員にとっての経験を改善する方法を理解します。",
|
||||
"xpack.observability.emptySection.apps.ux.link": "Rum エージェントをインストール",
|
||||
"xpack.observability.emptySection.apps.ux.title": "ユーザーエクスペリエンス",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentDescription": "API応答でElasticsearchクエリを調査します。",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentName": "ESクエリを調査",
|
||||
"xpack.observability.exp.breakDownFilter.noBreakdown": "内訳なし",
|
||||
"xpack.observability.experimentalBadgeDescription": "この機能は実験的機能であり、将来のリリースでは変更されたり完全に削除されたりする場合があります。Elasticは最善の努力を講じてすべての問題の修正に努めますが、実験的機能には正式なGA機能のサポートSLAが適用されません。",
|
||||
"xpack.observability.experimentalBadgeLabel": "実験的",
|
||||
"xpack.observability.exploratoryView.noBrusing": "ブラシ選択によるズームは時系列グラフでのみ使用できます。",
|
||||
"xpack.observability.expView.chartTypes.label": "チャートタイプ",
|
||||
"xpack.observability.expView.columns.label": "{sourceField}の{percentileValue}パーセンタイル",
|
||||
"xpack.observability.expView.columns.operation.label": "{sourceField}の{operationType}",
|
||||
"xpack.observability.expView.dateRanger.endDate": "終了日",
|
||||
"xpack.observability.expView.dateRanger.startDate": "開始日",
|
||||
"xpack.observability.expView.fieldLabels.agentHost": "エージェントホスト",
|
||||
"xpack.observability.expView.fieldLabels.backend": "バックエンド時刻",
|
||||
"xpack.observability.expView.fieldLabels.browserFamily": "ブラウザーファミリー",
|
||||
"xpack.observability.expView.fieldLabels.browserVersion": "ブラウザーバージョン",
|
||||
"xpack.observability.expView.fieldLabels.carrierLocation": "キャリアの位置情報",
|
||||
"xpack.observability.expView.fieldLabels.carrierName": "キャリア名",
|
||||
"xpack.observability.expView.fieldLabels.cls": "累積レイアウト変更",
|
||||
"xpack.observability.expView.fieldLabels.connectionType": "接続タイプ",
|
||||
"xpack.observability.expView.fieldLabels.coreWebVitals": "コア Web バイタル",
|
||||
"xpack.observability.expView.fieldLabels.cpuUsage": "CPU使用状況",
|
||||
"xpack.observability.expView.fieldLabels.dcl": "DOMコンテンツが読み込まれました",
|
||||
"xpack.observability.expView.fieldLabels.device": "デバイス",
|
||||
"xpack.observability.expView.fieldLabels.deviceDistribution": "デバイス分布",
|
||||
"xpack.observability.expView.fieldLabels.deviceModel": "デバイスモデル",
|
||||
"xpack.observability.expView.fieldLabels.downPings": "Down Ping",
|
||||
"xpack.observability.expView.fieldLabels.environment": "環境",
|
||||
"xpack.observability.expView.fieldLabels.fcp": "初回コンテンツの描画",
|
||||
"xpack.observability.expView.fieldLabels.fid": "初回入力遅延",
|
||||
"xpack.observability.expView.fieldLabels.hostName": "ホスト名",
|
||||
"xpack.observability.expView.fieldLabels.hostOS": "ホストOS",
|
||||
"xpack.observability.expView.fieldLabels.kpi": "KPI",
|
||||
"xpack.observability.expView.fieldLabels.kpiOverTime": "一定期間のKPI",
|
||||
"xpack.observability.expView.fieldLabels.lcp": "最大コンテンツの描画",
|
||||
"xpack.observability.expView.fieldLabels.location": "場所",
|
||||
"xpack.observability.expView.fieldLabels.memoryUsage": "システムメモリー使用状況",
|
||||
"xpack.observability.expView.fieldLabels.metric": "メトリック",
|
||||
"xpack.observability.expView.fieldLabels.mobile.memoryUsage": "メモリー使用状況",
|
||||
"xpack.observability.expView.fieldLabels.mobileApp": "モバイルアプリ",
|
||||
"xpack.observability.expView.fieldLabels.mobileResponse": "モバイル応答",
|
||||
"xpack.observability.expView.fieldLabels.monitorDurationLabel": "監視期間",
|
||||
"xpack.observability.expView.fieldLabels.monitorId": "モニターID",
|
||||
"xpack.observability.expView.fieldLabels.monitorName": "モニター名",
|
||||
"xpack.observability.expView.fieldLabels.monitorStatus": "監視ステータス",
|
||||
"xpack.observability.expView.fieldLabels.monitorType": "モニタータイプ",
|
||||
"xpack.observability.expView.fieldLabels.numberOfDevices": "デバイス数",
|
||||
"xpack.observability.expView.fieldLabels.obsLocation": "Observerの位置情報",
|
||||
"xpack.observability.expView.fieldLabels.onload": "ドキュメント完了(読み込み時)",
|
||||
"xpack.observability.expView.fieldLabels.os": "オペレーティングシステム",
|
||||
"xpack.observability.expView.fieldLabels.osPlatform": "OSプラットフォーム",
|
||||
"xpack.observability.expView.fieldLabels.pageLoadTime": "ページ読み込み時間",
|
||||
"xpack.observability.expView.fieldLabels.pagesLoaded": "ページが読み込まれました",
|
||||
"xpack.observability.expView.fieldLabels.pageViews": "ページビュー",
|
||||
"xpack.observability.expView.fieldLabels.performanceDistribution": "パフォーマンス分布",
|
||||
"xpack.observability.expView.fieldLabels.pings": "ピング",
|
||||
"xpack.observability.expView.fieldLabels.port": "ポート",
|
||||
"xpack.observability.expView.fieldLabels.requestMethod": "リクエストメソッド",
|
||||
"xpack.observability.expView.fieldLabels.responseLatency": "レイテンシ",
|
||||
"xpack.observability.expView.fieldLabels.serviceName": "サービス名",
|
||||
"xpack.observability.expView.fieldLabels.serviceVersion": "サービスバージョン",
|
||||
"xpack.observability.expView.fieldLabels.tags": "タグ",
|
||||
"xpack.observability.expView.fieldLabels.tbt": "合計ブロック時間",
|
||||
"xpack.observability.expView.fieldLabels.transactionPerMinute": "スループット",
|
||||
"xpack.observability.expView.fieldLabels.upPings": "Up Ping",
|
||||
"xpack.observability.expView.fieldLabels.url": "URL",
|
||||
"xpack.observability.expView.fieldLabels.webApplication": "Webアプリケーション",
|
||||
"xpack.observability.expView.filterValueButton.negate": "{value}ではない",
|
||||
"xpack.observability.expView.heading.experimental": "実験的",
|
||||
"xpack.observability.expView.heading.label": "データを分析",
|
||||
"xpack.observability.expView.heading.openInLens": "Lensで開く",
|
||||
"xpack.observability.expView.heading.saveLensVisualization": "保存",
|
||||
"xpack.observability.expView.operationType.75thPercentile": "75パーセンタイル",
|
||||
"xpack.observability.expView.operationType.90thPercentile": "90パーセンタイル",
|
||||
"xpack.observability.expView.operationType.95thPercentile": "95パーセンタイル",
|
||||
"xpack.observability.expView.operationType.99thPercentile": "99パーセンタイル",
|
||||
"xpack.observability.expView.operationType.average": "平均",
|
||||
"xpack.observability.expView.operationType.median": "中央",
|
||||
"xpack.observability.expView.operationType.sum": "合計",
|
||||
"xpack.observability.expView.reportType.selectDataType": "ビジュアライゼーションを作成するデータ型を選択します。",
|
||||
"xpack.observability.expView.seriesBuilder.addSeries": "数列を追加",
|
||||
"xpack.observability.expView.seriesBuilder.apply": "変更を適用",
|
||||
"xpack.observability.expView.seriesBuilder.emptyReportDefinition": "ビジュアライゼーションを作成するレポート定義を選択します。",
|
||||
"xpack.observability.expView.seriesBuilder.emptyview": "表示する情報がありません。",
|
||||
"xpack.observability.expView.seriesBuilder.loadingView": "ビューを読み込んでいます...",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType": "レポートタイプが選択されていません",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType.empty": "レポートタイプを選択すると、ビジュアライゼーションを作成します。",
|
||||
"xpack.observability.expView.seriesEditor.clearFilter": "フィルターを消去",
|
||||
"xpack.observability.expView.seriesEditor.notFound": "系列が見つかりません。系列を追加してください。",
|
||||
"xpack.observability.expView.seriesEditor.removeSeries": "クリックすると、系列を削除します",
|
||||
"xpack.observability.featureCatalogueDescription": "専用UIで、ログ、メトリック、アプリケーショントレース、システム可用性を連結します。",
|
||||
"xpack.observability.featureCatalogueTitle": "オブザーバビリティ",
|
||||
"xpack.observability.featureRegistry.linkObservabilityTitle": "ケース",
|
||||
"xpack.observability.feedbackMenu.appName": "オブザーバビリティ",
|
||||
"xpack.observability.fieldValueSelection.apply": "適用",
|
||||
"xpack.observability.fieldValueSelection.loading": "読み込み中",
|
||||
"xpack.observability.fieldValueSelection.placeholder": "{label}をフィルタリング",
|
||||
"xpack.observability.fieldValueSelection.placeholder.search": "{label}を検索",
|
||||
"xpack.observability.filterButton.label": "{label}フィルターのフィルターグループを展開",
|
||||
"xpack.observability.filters.expanded.noFilter": "フィルターが見つかりません。",
|
||||
"xpack.observability.filters.expanded.search": "{label}を検索",
|
||||
"xpack.observability.fleet.button": "Fleetを試す",
|
||||
"xpack.observability.fleet.text": "Elastic エージェントでは、シンプルかつ統合された方法で、ログ、メトリック、他の種類のデータの監視をホストに追加することができます。複数の Beats と他のエージェントをインストールする必要はありません。このため、インフラストラクチャ全体での構成のデプロイが簡単で高速になりました。",
|
||||
"xpack.observability.fleet.title": "新しい Fleet をご覧になりましたか。",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabel": "h",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabelExtended": "時間",
|
||||
"xpack.observability.formatters.microsTimeUnitLabel": "μs",
|
||||
"xpack.observability.formatters.microsTimeUnitLabelExtended": "マイクロ秒",
|
||||
"xpack.observability.formatters.millisTimeUnitLabel": "ms",
|
||||
"xpack.observability.formatters.millisTimeUnitLabelExtended": "ミリ秒",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabel": "分",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabelExtended": "分",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabel": "s",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒",
|
||||
"xpack.observability.home.addData": "データの追加",
|
||||
"xpack.observability.navigation.newBadge": "新規",
|
||||
"xpack.observability.news.readFullStory": "詳細なストーリーを読む",
|
||||
"xpack.observability.news.title": "新機能",
|
||||
"xpack.observability.notAvailable": "N/A",
|
||||
"xpack.observability.overview.alert.allTypes": "すべてのタイプ",
|
||||
"xpack.observability.overview.alert.appLink": "アラートを管理",
|
||||
"xpack.observability.overview.alerts.muted": "ミュート",
|
||||
"xpack.observability.overview.alerts.title": "アラート",
|
||||
"xpack.observability.overview.apm.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.apm.services": "サービス",
|
||||
"xpack.observability.overview.apm.throughput": "スループット",
|
||||
"xpack.observability.overview.apm.title": "APM",
|
||||
"xpack.observability.overview.exploratoryView": "データを分析",
|
||||
"xpack.observability.overview.exploratoryView.lensDisabled": "Lensアプリを使用できません。調査ビューを使用するには、Lensを有効にしてください。",
|
||||
"xpack.observability.overview.loadingObservability": "オブザーバビリティを読み込んでいます",
|
||||
"xpack.observability.overview.logs.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.logs.subtitle": "毎分のログレート",
|
||||
"xpack.observability.overview.logs.title": "ログ",
|
||||
"xpack.observability.overview.metrics.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.metrics.colunms.cpu": "CPU %",
|
||||
"xpack.observability.overview.metrics.colunms.hostname": "ホスト名",
|
||||
"xpack.observability.overview.metrics.colunms.load15": "読み込み15",
|
||||
"xpack.observability.overview.metrics.colunms.uptime": "アップタイム",
|
||||
"xpack.observability.overview.metrics.title": "メトリック",
|
||||
"xpack.observability.overview.pageTitle": "概要",
|
||||
"xpack.observability.overview.uptime.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.uptime.chart.down": "ダウン",
|
||||
"xpack.observability.overview.uptime.chart.up": "アップ",
|
||||
"xpack.observability.overview.uptime.down": "ダウン",
|
||||
"xpack.observability.overview.uptime.monitors": "監視",
|
||||
"xpack.observability.overview.uptime.title": "アップタイム",
|
||||
"xpack.observability.overview.uptime.up": "アップ",
|
||||
"xpack.observability.overview.ux.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.ux.title": "ユーザーエクスペリエンス",
|
||||
"xpack.observability.overviewLinkTitle": "概要",
|
||||
"xpack.observability.pageLayout.sideNavTitle": "オブザーバビリティ",
|
||||
"xpack.observability.resources.documentation": "ドキュメント",
|
||||
"xpack.observability.resources.forum": "ディスカッションフォーラム",
|
||||
"xpack.observability.resources.quick_start": "クイックスタートビデオ",
|
||||
"xpack.observability.resources.title": "リソース",
|
||||
"xpack.observability.resources.training": "無料のObservabilityコース",
|
||||
"xpack.observability.section.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。",
|
||||
"xpack.observability.section.apps.apm.title": "APM",
|
||||
"xpack.observability.section.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。",
|
||||
"xpack.observability.section.apps.logs.title": "ログ",
|
||||
"xpack.observability.section.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。",
|
||||
"xpack.observability.section.apps.metrics.title": "メトリック",
|
||||
"xpack.observability.section.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。",
|
||||
"xpack.observability.section.apps.uptime.title": "アップタイム",
|
||||
"xpack.observability.section.errorPanel": "データの取得時にエラーが発生しました。再試行してください",
|
||||
"xpack.observability.seriesEditor.clone": "系列をコピー",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.ux.coreVitals.average": "平均",
|
||||
"xpack.observability.ux.coreVitals.averageMessage": " {bad}未満",
|
||||
"xpack.observability.ux.coreVitals.cls": "累積レイアウト変更",
|
||||
"xpack.observability.ux.coreVitals.cls.help": "累積レイアウト変更(CLS):視覚的な安定性を計測します。優れたユーザーエクスペリエンスを実現するには、ページのCLSを0.1未満に保ってください。",
|
||||
"xpack.observability.ux.coreVitals.fid.help": "初回入力遅延(FID)は双方向性を計測します。優れたユーザーエクスペリエンスを実現するには、ページのFIDを100ミリ秒未満に保ってください。",
|
||||
"xpack.observability.ux.coreVitals.fip": "初回入力遅延",
|
||||
"xpack.observability.ux.coreVitals.good": "優れている",
|
||||
"xpack.observability.ux.coreVitals.is": "is",
|
||||
"xpack.observability.ux.coreVitals.lcp": "最大コンテンツの描画",
|
||||
"xpack.observability.ux.coreVitals.lcp.help": "最大コンテンツの描画(LCP)は読み込みパフォーマンスを計測します。優れたユーザーエクスペリエンスを実現するには、ページの読み込みが開始した後、2.5秒以内にLCPが実行されるようにしてください。",
|
||||
"xpack.observability.ux.coreVitals.legends.good": "優れている",
|
||||
"xpack.observability.ux.coreVitals.legends.needsImprovement": "要改善",
|
||||
"xpack.observability.ux.coreVitals.legends.poor": "悪い",
|
||||
"xpack.observability.ux.coreVitals.less": "少ない",
|
||||
"xpack.observability.ux.coreVitals.more": "多い",
|
||||
"xpack.observability.ux.coreVitals.noData": "利用可能なデータがありません。",
|
||||
"xpack.observability.ux.coreVitals.paletteLegend.rankPercentage": "{labelsInd} ({ranksInd}%)",
|
||||
"xpack.observability.ux.coreVitals.poor": "悪い",
|
||||
"xpack.observability.ux.coreVitals.takes": "取得",
|
||||
"xpack.observability.ux.coreWebVitals": "コア Web バイタル",
|
||||
"xpack.observability.ux.coreWebVitals.browser.support": "コア Web バイタルのブラウザーサポート",
|
||||
"xpack.observability.ux.coreWebVitals.service": "サービス",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.browser.help": "詳細",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.help": "詳細",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "ヘルプ",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.traffic": "トラフィックの {trafficPerc} が表示されました",
|
||||
"xpack.observability.ux.dashboard.webVitals.palette.tooltip": "{title} は {value}{averageMessage}より{moreOrLess}{isOrTakes}ため、{percentage} %のユーザーが{exp}を経験しています。",
|
||||
"xpack.observability.ux.service.help": "最大トラフィックのRUMサービスが選択されています",
|
||||
"xpack.banners.settings.backgroundColor.description": "バナーの背景色。{subscriptionLink}",
|
||||
"xpack.banners.settings.backgroundColor.title": "バナー背景色",
|
||||
"xpack.banners.settings.placement.description": "Elasticヘッダーの上に、このスペースの上部のバナーを表示します。{subscriptionLink}",
|
||||
|
@ -18737,286 +19016,6 @@
|
|||
"xpack.monitoring.updateLicenseButtonLabel": "ライセンスを更新",
|
||||
"xpack.monitoring.updateLicenseTitle": "ライセンスの更新",
|
||||
"xpack.monitoring.useAvailableLicenseDescription": "すでに新しいライセンスがある場合は、今すぐアップロードしてください。",
|
||||
"xpack.observability.alerts.manageRulesButtonLabel": "ルールの管理",
|
||||
"xpack.observability.alerts.searchBarPlaceholder": "kibana.alert.evaluation.threshold > 75",
|
||||
"xpack.observability.alertsDisclaimerLinkText": "アラートとアクション",
|
||||
"xpack.observability.alertsDisclaimerText": "このページには実験アラートビューが表示されます。ここに表示されるデータは、アラートを正確に表していない可能性があります。アラートの非実験リストは、スタック管理のアラートとアクション設定にあります。",
|
||||
"xpack.observability.alertsDisclaimerTitle": "実験的",
|
||||
"xpack.observability.alertsFlyout.actualValueLabel": "実際の値",
|
||||
"xpack.observability.alertsFlyout.durationLabel": "期間",
|
||||
"xpack.observability.alertsFlyout.expectedValueLabel": "想定された値",
|
||||
"xpack.observability.alertsFlyout.ruleTypeLabel": "ルールタイプ",
|
||||
"xpack.observability.alertsFlyout.statusLabel": "ステータス",
|
||||
"xpack.observability.alertsLinkTitle": "アラート",
|
||||
"xpack.observability.alertsTable.actionsTextLabel": "アクション",
|
||||
"xpack.observability.alertsTable.footerTextLabel": "アラート",
|
||||
"xpack.observability.alertsTable.loadingTextLabel": "アラートを読み込んでいます",
|
||||
"xpack.observability.alertsTGrid.durationColumnDescription": "期間",
|
||||
"xpack.observability.alertsTGrid.lastUpdatedColumnDescription": "最終更新",
|
||||
"xpack.observability.alertsTGrid.reasonColumnDescription": "理由",
|
||||
"xpack.observability.alertsTGrid.statusColumnDescription": "ステータス",
|
||||
"xpack.observability.alertsTitle": "アラート",
|
||||
"xpack.observability.breadcrumbs.alertsLinkText": "アラート",
|
||||
"xpack.observability.breadcrumbs.casesConfigureLinkText": "構成",
|
||||
"xpack.observability.breadcrumbs.casesCreateLinkText": "作成",
|
||||
"xpack.observability.breadcrumbs.casesLinkText": "ケース",
|
||||
"xpack.observability.breadcrumbs.landingLinkText": "はじめて使う",
|
||||
"xpack.observability.breadcrumbs.observabilityLinkText": "オブザーバビリティ",
|
||||
"xpack.observability.breadcrumbs.overviewLinkText": "概要",
|
||||
"xpack.observability.cases.allCases.actions": "アクション",
|
||||
"xpack.observability.cases.allCases.comments": "コメント",
|
||||
"xpack.observability.cases.allCases.noTagsAvailable": "利用可能なタグがありません",
|
||||
"xpack.observability.cases.badge.readOnly.text": "読み取り専用",
|
||||
"xpack.observability.cases.badge.readOnly.tooltip": "ケースを作成または編集できません",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsMessage": "ケースを表示するには、Kibana スペースでケース機能の権限が必要です。詳細については、Kibana管理者に連絡してください。",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsTitle": "Kibana機能権限が必要です",
|
||||
"xpack.observability.cases.caseView.backLabel": "ケースに戻る",
|
||||
"xpack.observability.cases.caseView.cancel": "キャンセル",
|
||||
"xpack.observability.cases.caseView.caseName": "ケース名",
|
||||
"xpack.observability.cases.caseView.closeCase": "ケースを閉じる",
|
||||
"xpack.observability.cases.caseView.comment.addComment": "コメントを追加",
|
||||
"xpack.observability.cases.caseView.comment.addCommentHelpText": "新しいコメントを追加...",
|
||||
"xpack.observability.cases.caseView.commentFieldRequiredError": "コメントが必要です。",
|
||||
"xpack.observability.cases.caseView.connectors": "外部インシデント管理システム",
|
||||
"xpack.observability.cases.caseView.create": "新規ケースを作成",
|
||||
"xpack.observability.cases.caseView.createCase": "ケースを作成",
|
||||
"xpack.observability.cases.caseView.description": "説明",
|
||||
"xpack.observability.cases.caseView.description.save": "保存",
|
||||
"xpack.observability.cases.caseView.edit": "編集",
|
||||
"xpack.observability.cases.caseView.editConnector": "外部インシデント管理システムを変更",
|
||||
"xpack.observability.cases.caseView.fieldRequiredError": "必須フィールド",
|
||||
"xpack.observability.cases.caseView.goToDocumentationButton": "ドキュメンテーションを表示",
|
||||
"xpack.observability.cases.caseView.name": "名前",
|
||||
"xpack.observability.cases.caseView.noReportersAvailable": "利用可能なレポートがありません。",
|
||||
"xpack.observability.cases.caseView.noTags": "現在、このケースにタグは割り当てられていません。",
|
||||
"xpack.observability.cases.caseView.optional": "オプション",
|
||||
"xpack.observability.cases.caseView.particpantsLabel": "参加者",
|
||||
"xpack.observability.cases.caseView.reopenCase": "ケースを再開",
|
||||
"xpack.observability.cases.caseView.reporterLabel": "報告者",
|
||||
"xpack.observability.cases.caseView.tags": "タグ",
|
||||
"xpack.observability.cases.caseView.to": "に",
|
||||
"xpack.observability.cases.configureCases.headerTitle": "ケースを構成",
|
||||
"xpack.observability.cases.configureCasesButton": "外部接続を編集",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCase": "ケースを削除",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCases": "ケースを削除",
|
||||
"xpack.observability.cases.createCase.descriptionFieldRequiredError": "説明が必要です。",
|
||||
"xpack.observability.cases.createCase.fieldTagsHelpText": "このケースの1つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。",
|
||||
"xpack.observability.cases.createCase.titleFieldRequiredError": "タイトルが必要です。",
|
||||
"xpack.observability.cases.dismissErrorsPushServiceCallOutTitle": "閉じる",
|
||||
"xpack.observability.cases.pageTitle": "ケース",
|
||||
"xpack.observability.casesLinkTitle": "ケース",
|
||||
"xpack.observability.emptySection.apps.alert.description": "503 エラーが累積していますか?サービスは応答していますか?CPUとRAMの使用量が跳ね上がっていますか?このような警告を、事後にではなく、発生と同時に把握しましょう。",
|
||||
"xpack.observability.emptySection.apps.alert.link": "ルールを作成",
|
||||
"xpack.observability.emptySection.apps.alert.title": "アラートが見つかりません。",
|
||||
"xpack.observability.emptySection.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。",
|
||||
"xpack.observability.emptySection.apps.apm.link": "エージェントのインストール",
|
||||
"xpack.observability.emptySection.apps.apm.title": "APM",
|
||||
"xpack.observability.emptySection.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。",
|
||||
"xpack.observability.emptySection.apps.logs.link": "Filebeatをインストール",
|
||||
"xpack.observability.emptySection.apps.logs.title": "ログ",
|
||||
"xpack.observability.emptySection.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。",
|
||||
"xpack.observability.emptySection.apps.metrics.link": "Metricbeatのインストール",
|
||||
"xpack.observability.emptySection.apps.metrics.title": "メトリック",
|
||||
"xpack.observability.emptySection.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。",
|
||||
"xpack.observability.emptySection.apps.uptime.link": "Heartbeatのインストール",
|
||||
"xpack.observability.emptySection.apps.uptime.title": "アップタイム",
|
||||
"xpack.observability.emptySection.apps.ux.description": "パフォーマンスは分散です。Web アプリケーションにアクセスするすべてのユーザーの経験を計測し、全員にとっての経験を改善する方法を理解します。",
|
||||
"xpack.observability.emptySection.apps.ux.link": "Rum エージェントをインストール",
|
||||
"xpack.observability.emptySection.apps.ux.title": "ユーザーエクスペリエンス",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentDescription": "API応答でElasticsearchクエリを調査します。",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentName": "ESクエリを調査",
|
||||
"xpack.observability.exp.breakDownFilter.noBreakdown": "内訳なし",
|
||||
"xpack.observability.experimentalBadgeDescription": "この機能は実験的機能であり、将来のリリースでは変更されたり完全に削除されたりする場合があります。Elasticは最善の努力を講じてすべての問題の修正に努めますが、実験的機能には正式なGA機能のサポートSLAが適用されません。",
|
||||
"xpack.observability.experimentalBadgeLabel": "実験的",
|
||||
"xpack.observability.exploratoryView.noBrusing": "ブラシ選択によるズームは時系列グラフでのみ使用できます。",
|
||||
"xpack.observability.expView.chartTypes.label": "チャートタイプ",
|
||||
"xpack.observability.expView.columns.label": "{sourceField}の{percentileValue}パーセンタイル",
|
||||
"xpack.observability.expView.columns.operation.label": "{sourceField}の{operationType}",
|
||||
"xpack.observability.expView.dateRanger.endDate": "終了日",
|
||||
"xpack.observability.expView.dateRanger.startDate": "開始日",
|
||||
"xpack.observability.expView.fieldLabels.agentHost": "エージェントホスト",
|
||||
"xpack.observability.expView.fieldLabels.backend": "バックエンド時刻",
|
||||
"xpack.observability.expView.fieldLabels.browserFamily": "ブラウザーファミリー",
|
||||
"xpack.observability.expView.fieldLabels.browserVersion": "ブラウザーバージョン",
|
||||
"xpack.observability.expView.fieldLabels.carrierLocation": "キャリアの位置情報",
|
||||
"xpack.observability.expView.fieldLabels.carrierName": "キャリア名",
|
||||
"xpack.observability.expView.fieldLabels.cls": "累積レイアウト変更",
|
||||
"xpack.observability.expView.fieldLabels.connectionType": "接続タイプ",
|
||||
"xpack.observability.expView.fieldLabels.coreWebVitals": "コア Web バイタル",
|
||||
"xpack.observability.expView.fieldLabels.cpuUsage": "CPU使用状況",
|
||||
"xpack.observability.expView.fieldLabels.dcl": "DOMコンテンツが読み込まれました",
|
||||
"xpack.observability.expView.fieldLabels.device": "デバイス",
|
||||
"xpack.observability.expView.fieldLabels.deviceDistribution": "デバイス分布",
|
||||
"xpack.observability.expView.fieldLabels.deviceModel": "デバイスモデル",
|
||||
"xpack.observability.expView.fieldLabels.downPings": "Down Ping",
|
||||
"xpack.observability.expView.fieldLabels.environment": "環境",
|
||||
"xpack.observability.expView.fieldLabels.fcp": "初回コンテンツの描画",
|
||||
"xpack.observability.expView.fieldLabels.fid": "初回入力遅延",
|
||||
"xpack.observability.expView.fieldLabels.hostName": "ホスト名",
|
||||
"xpack.observability.expView.fieldLabels.hostOS": "ホストOS",
|
||||
"xpack.observability.expView.fieldLabels.kpi": "KPI",
|
||||
"xpack.observability.expView.fieldLabels.kpiOverTime": "一定期間のKPI",
|
||||
"xpack.observability.expView.fieldLabels.lcp": "最大コンテンツの描画",
|
||||
"xpack.observability.expView.fieldLabels.location": "場所",
|
||||
"xpack.observability.expView.fieldLabels.memoryUsage": "システムメモリー使用状況",
|
||||
"xpack.observability.expView.fieldLabels.metric": "メトリック",
|
||||
"xpack.observability.expView.fieldLabels.mobile.memoryUsage": "メモリー使用状況",
|
||||
"xpack.observability.expView.fieldLabels.mobileApp": "モバイルアプリ",
|
||||
"xpack.observability.expView.fieldLabels.mobileResponse": "モバイル応答",
|
||||
"xpack.observability.expView.fieldLabels.monitorDurationLabel": "監視期間",
|
||||
"xpack.observability.expView.fieldLabels.monitorId": "モニターID",
|
||||
"xpack.observability.expView.fieldLabels.monitorName": "モニター名",
|
||||
"xpack.observability.expView.fieldLabels.monitorStatus": "監視ステータス",
|
||||
"xpack.observability.expView.fieldLabels.monitorType": "モニタータイプ",
|
||||
"xpack.observability.expView.fieldLabels.numberOfDevices": "デバイス数",
|
||||
"xpack.observability.expView.fieldLabels.obsLocation": "Observerの位置情報",
|
||||
"xpack.observability.expView.fieldLabels.onload": "ドキュメント完了(読み込み時)",
|
||||
"xpack.observability.expView.fieldLabels.os": "オペレーティングシステム",
|
||||
"xpack.observability.expView.fieldLabels.osPlatform": "OSプラットフォーム",
|
||||
"xpack.observability.expView.fieldLabels.pageLoadTime": "ページ読み込み時間",
|
||||
"xpack.observability.expView.fieldLabels.pagesLoaded": "ページが読み込まれました",
|
||||
"xpack.observability.expView.fieldLabels.pageViews": "ページビュー",
|
||||
"xpack.observability.expView.fieldLabels.performanceDistribution": "パフォーマンス分布",
|
||||
"xpack.observability.expView.fieldLabels.pings": "ピング",
|
||||
"xpack.observability.expView.fieldLabels.port": "ポート",
|
||||
"xpack.observability.expView.fieldLabels.requestMethod": "リクエストメソッド",
|
||||
"xpack.observability.expView.fieldLabels.responseLatency": "レイテンシ",
|
||||
"xpack.observability.expView.fieldLabels.serviceName": "サービス名",
|
||||
"xpack.observability.expView.fieldLabels.serviceVersion": "サービスバージョン",
|
||||
"xpack.observability.expView.fieldLabels.tags": "タグ",
|
||||
"xpack.observability.expView.fieldLabels.tbt": "合計ブロック時間",
|
||||
"xpack.observability.expView.fieldLabels.transactionPerMinute": "スループット",
|
||||
"xpack.observability.expView.fieldLabels.upPings": "Up Ping",
|
||||
"xpack.observability.expView.fieldLabels.url": "URL",
|
||||
"xpack.observability.expView.fieldLabels.webApplication": "Webアプリケーション",
|
||||
"xpack.observability.expView.filterValueButton.negate": "{value}ではない",
|
||||
"xpack.observability.expView.heading.experimental": "実験的",
|
||||
"xpack.observability.expView.heading.label": "データを分析",
|
||||
"xpack.observability.expView.heading.openInLens": "Lensで開く",
|
||||
"xpack.observability.expView.heading.saveLensVisualization": "保存",
|
||||
"xpack.observability.expView.operationType.75thPercentile": "75パーセンタイル",
|
||||
"xpack.observability.expView.operationType.90thPercentile": "90パーセンタイル",
|
||||
"xpack.observability.expView.operationType.95thPercentile": "95パーセンタイル",
|
||||
"xpack.observability.expView.operationType.99thPercentile": "99パーセンタイル",
|
||||
"xpack.observability.expView.operationType.average": "平均",
|
||||
"xpack.observability.expView.operationType.median": "中央",
|
||||
"xpack.observability.expView.operationType.sum": "合計",
|
||||
"xpack.observability.expView.reportType.selectDataType": "ビジュアライゼーションを作成するデータ型を選択します。",
|
||||
"xpack.observability.expView.seriesBuilder.addSeries": "数列を追加",
|
||||
"xpack.observability.expView.seriesBuilder.apply": "変更を適用",
|
||||
"xpack.observability.expView.seriesBuilder.emptyReportDefinition": "ビジュアライゼーションを作成するレポート定義を選択します。",
|
||||
"xpack.observability.expView.seriesBuilder.emptyview": "表示する情報がありません。",
|
||||
"xpack.observability.expView.seriesBuilder.loadingView": "ビューを読み込んでいます...",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType": "レポートタイプが選択されていません",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType.empty": "レポートタイプを選択すると、ビジュアライゼーションを作成します。",
|
||||
"xpack.observability.expView.seriesEditor.clearFilter": "フィルターを消去",
|
||||
"xpack.observability.expView.seriesEditor.notFound": "系列が見つかりません。系列を追加してください。",
|
||||
"xpack.observability.expView.seriesEditor.removeSeries": "クリックすると、系列を削除します",
|
||||
"xpack.observability.featureCatalogueDescription": "専用UIで、ログ、メトリック、アプリケーショントレース、システム可用性を連結します。",
|
||||
"xpack.observability.featureCatalogueTitle": "オブザーバビリティ",
|
||||
"xpack.observability.featureRegistry.linkObservabilityTitle": "ケース",
|
||||
"xpack.observability.feedbackMenu.appName": "オブザーバビリティ",
|
||||
"xpack.observability.fieldValueSelection.apply": "適用",
|
||||
"xpack.observability.fieldValueSelection.loading": "読み込み中",
|
||||
"xpack.observability.fieldValueSelection.placeholder": "{label}をフィルタリング",
|
||||
"xpack.observability.fieldValueSelection.placeholder.search": "{label}を検索",
|
||||
"xpack.observability.filterButton.label": "{label}フィルターのフィルターグループを展開",
|
||||
"xpack.observability.filters.expanded.noFilter": "フィルターが見つかりません。",
|
||||
"xpack.observability.filters.expanded.search": "{label}を検索",
|
||||
"xpack.observability.fleet.button": "Fleetを試す",
|
||||
"xpack.observability.fleet.text": "Elastic エージェントでは、シンプルかつ統合された方法で、ログ、メトリック、他の種類のデータの監視をホストに追加することができます。複数の Beats と他のエージェントをインストールする必要はありません。このため、インフラストラクチャ全体での構成のデプロイが簡単で高速になりました。",
|
||||
"xpack.observability.fleet.title": "新しい Fleet をご覧になりましたか。",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabel": "h",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabelExtended": "時間",
|
||||
"xpack.observability.formatters.microsTimeUnitLabel": "μs",
|
||||
"xpack.observability.formatters.microsTimeUnitLabelExtended": "マイクロ秒",
|
||||
"xpack.observability.formatters.millisTimeUnitLabel": "ms",
|
||||
"xpack.observability.formatters.millisTimeUnitLabelExtended": "ミリ秒",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabel": "分",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabelExtended": "分",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabel": "s",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒",
|
||||
"xpack.observability.home.addData": "データの追加",
|
||||
"xpack.observability.navigation.newBadge": "新規",
|
||||
"xpack.observability.news.readFullStory": "詳細なストーリーを読む",
|
||||
"xpack.observability.news.title": "新機能",
|
||||
"xpack.observability.notAvailable": "N/A",
|
||||
"xpack.observability.overview.alert.allTypes": "すべてのタイプ",
|
||||
"xpack.observability.overview.alert.appLink": "アラートを管理",
|
||||
"xpack.observability.overview.alerts.muted": "ミュート",
|
||||
"xpack.observability.overview.alerts.title": "アラート",
|
||||
"xpack.observability.overview.apm.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.apm.services": "サービス",
|
||||
"xpack.observability.overview.apm.throughput": "スループット",
|
||||
"xpack.observability.overview.apm.title": "APM",
|
||||
"xpack.observability.overview.exploratoryView": "データを分析",
|
||||
"xpack.observability.overview.exploratoryView.lensDisabled": "Lensアプリを使用できません。調査ビューを使用するには、Lensを有効にしてください。",
|
||||
"xpack.observability.overview.loadingObservability": "オブザーバビリティを読み込んでいます",
|
||||
"xpack.observability.overview.logs.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.logs.subtitle": "毎分のログレート",
|
||||
"xpack.observability.overview.logs.title": "ログ",
|
||||
"xpack.observability.overview.metrics.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.metrics.colunms.cpu": "CPU %",
|
||||
"xpack.observability.overview.metrics.colunms.hostname": "ホスト名",
|
||||
"xpack.observability.overview.metrics.colunms.load15": "読み込み15",
|
||||
"xpack.observability.overview.metrics.colunms.uptime": "アップタイム",
|
||||
"xpack.observability.overview.metrics.title": "メトリック",
|
||||
"xpack.observability.overview.pageTitle": "概要",
|
||||
"xpack.observability.overview.uptime.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.uptime.chart.down": "ダウン",
|
||||
"xpack.observability.overview.uptime.chart.up": "アップ",
|
||||
"xpack.observability.overview.uptime.down": "ダウン",
|
||||
"xpack.observability.overview.uptime.monitors": "監視",
|
||||
"xpack.observability.overview.uptime.title": "アップタイム",
|
||||
"xpack.observability.overview.uptime.up": "アップ",
|
||||
"xpack.observability.overview.ux.appLink": "アプリで表示",
|
||||
"xpack.observability.overview.ux.title": "ユーザーエクスペリエンス",
|
||||
"xpack.observability.overviewLinkTitle": "概要",
|
||||
"xpack.observability.pageLayout.sideNavTitle": "オブザーバビリティ",
|
||||
"xpack.observability.resources.documentation": "ドキュメント",
|
||||
"xpack.observability.resources.forum": "ディスカッションフォーラム",
|
||||
"xpack.observability.resources.quick_start": "クイックスタートビデオ",
|
||||
"xpack.observability.resources.title": "リソース",
|
||||
"xpack.observability.resources.training": "無料のObservabilityコース",
|
||||
"xpack.observability.section.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。",
|
||||
"xpack.observability.section.apps.apm.title": "APM",
|
||||
"xpack.observability.section.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。",
|
||||
"xpack.observability.section.apps.logs.title": "ログ",
|
||||
"xpack.observability.section.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。",
|
||||
"xpack.observability.section.apps.metrics.title": "メトリック",
|
||||
"xpack.observability.section.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。",
|
||||
"xpack.observability.section.apps.uptime.title": "アップタイム",
|
||||
"xpack.observability.section.errorPanel": "データの取得時にエラーが発生しました。再試行してください",
|
||||
"xpack.observability.seriesEditor.clone": "系列をコピー",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.ux.coreVitals.average": "平均",
|
||||
"xpack.observability.ux.coreVitals.averageMessage": " {bad}未満",
|
||||
"xpack.observability.ux.coreVitals.cls": "累積レイアウト変更",
|
||||
"xpack.observability.ux.coreVitals.cls.help": "累積レイアウト変更(CLS):視覚的な安定性を計測します。優れたユーザーエクスペリエンスを実現するには、ページのCLSを0.1未満に保ってください。",
|
||||
"xpack.observability.ux.coreVitals.fid.help": "初回入力遅延(FID)は双方向性を計測します。優れたユーザーエクスペリエンスを実現するには、ページのFIDを100ミリ秒未満に保ってください。",
|
||||
"xpack.observability.ux.coreVitals.fip": "初回入力遅延",
|
||||
"xpack.observability.ux.coreVitals.good": "優れている",
|
||||
"xpack.observability.ux.coreVitals.is": "is",
|
||||
"xpack.observability.ux.coreVitals.lcp": "最大コンテンツの描画",
|
||||
"xpack.observability.ux.coreVitals.lcp.help": "最大コンテンツの描画(LCP)は読み込みパフォーマンスを計測します。優れたユーザーエクスペリエンスを実現するには、ページの読み込みが開始した後、2.5秒以内にLCPが実行されるようにしてください。",
|
||||
"xpack.observability.ux.coreVitals.legends.good": "優れている",
|
||||
"xpack.observability.ux.coreVitals.legends.needsImprovement": "要改善",
|
||||
"xpack.observability.ux.coreVitals.legends.poor": "悪い",
|
||||
"xpack.observability.ux.coreVitals.less": "少ない",
|
||||
"xpack.observability.ux.coreVitals.more": "多い",
|
||||
"xpack.observability.ux.coreVitals.noData": "利用可能なデータがありません。",
|
||||
"xpack.observability.ux.coreVitals.paletteLegend.rankPercentage": "{labelsInd} ({ranksInd}%)",
|
||||
"xpack.observability.ux.coreVitals.poor": "悪い",
|
||||
"xpack.observability.ux.coreVitals.takes": "取得",
|
||||
"xpack.observability.ux.coreWebVitals": "コア Web バイタル",
|
||||
"xpack.observability.ux.coreWebVitals.browser.support": "コア Web バイタルのブラウザーサポート",
|
||||
"xpack.observability.ux.coreWebVitals.service": "サービス",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.browser.help": "詳細",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.help": "詳細",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "ヘルプ",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.traffic": "トラフィックの {trafficPerc} が表示されました",
|
||||
"xpack.observability.ux.dashboard.webVitals.palette.tooltip": "{title} は {value}{averageMessage}より{moreOrLess}{isOrTakes}ため、{percentage} %のユーザーが{exp}を経験しています。",
|
||||
"xpack.observability.ux.service.help": "最大トラフィックのRUMサービスが選択されています",
|
||||
"xpack.osquery.action_details.fetchError": "アクション詳細の取得中にエラーが発生しました",
|
||||
"xpack.osquery.action_policy_details.fetchError": "ポリシー詳細の取得中にエラーが発生しました",
|
||||
"xpack.osquery.action_results.errorSearchDescription": "アクション結果検索でエラーが発生しました",
|
||||
|
|
|
@ -6275,7 +6275,6 @@
|
|||
"xpack.apm.apmDescription": "自动从您的应用程序内收集深层的性能指标和错误。",
|
||||
"xpack.apm.apmSchema.index": "APM Server 架构 - 索引",
|
||||
"xpack.apm.apmSettings.index": "APM 设置 - 索引",
|
||||
"xpack.apm.apply.label": "应用",
|
||||
"xpack.apm.backendDetail.dependenciesTableColumnBackend": "服务",
|
||||
"xpack.apm.backendDetail.dependenciesTableTitle": "上游服务",
|
||||
"xpack.apm.backendDetailFailedTransactionRateChartTitle": "失败事务率",
|
||||
|
@ -6338,7 +6337,6 @@
|
|||
"xpack.apm.csm.breakDownFilter.noBreakdown": "无细目",
|
||||
"xpack.apm.csm.breakdownFilter.os": "OS",
|
||||
"xpack.apm.csm.pageViews.analyze": "分析",
|
||||
"xpack.apm.csm.search.url.close": "关闭",
|
||||
"xpack.apm.customLink.buttom.create": "创建定制链接",
|
||||
"xpack.apm.customLink.buttom.create.title": "创建",
|
||||
"xpack.apm.customLink.buttom.manage": "管理定制链接",
|
||||
|
@ -6545,13 +6543,6 @@
|
|||
"xpack.apm.rum.filterGroup.coreWebVitals": "网站体验核心指标",
|
||||
"xpack.apm.rum.filterGroup.seconds": "秒",
|
||||
"xpack.apm.rum.filterGroup.selectBreakdown": "选择细分",
|
||||
"xpack.apm.rum.filters.filterByUrl": "按 URL 筛选",
|
||||
"xpack.apm.rum.filters.searchResults": "{total} 项搜索结果",
|
||||
"xpack.apm.rum.filters.select": "选择",
|
||||
"xpack.apm.rum.filters.topPages": "排名靠前页面",
|
||||
"xpack.apm.rum.filters.url": "URL",
|
||||
"xpack.apm.rum.filters.url.loadingResults": "正在加载结果",
|
||||
"xpack.apm.rum.filters.url.noResults": "没有可用结果",
|
||||
"xpack.apm.rum.jsErrors.errorMessage": "错误消息",
|
||||
"xpack.apm.rum.jsErrors.errorRate": "错误率",
|
||||
"xpack.apm.rum.jsErrors.impactedPageLoads": "受影响的页面加载",
|
||||
|
@ -7089,7 +7080,6 @@
|
|||
"xpack.apm.ux.percentile.label": "百分位数",
|
||||
"xpack.apm.ux.percentiles.label": "第 {value} 个百分位",
|
||||
"xpack.apm.ux.title": "仪表板",
|
||||
"xpack.apm.ux.url.hitEnter.include": "按 {icon} 或单击“应用”可包括与 {searchValue} 匹配的所有 URL",
|
||||
"xpack.apm.ux.visitorBreakdown.noData": "无数据。",
|
||||
"xpack.apm.views.dependencies.title": "依赖项",
|
||||
"xpack.apm.views.errors.title": "错误",
|
||||
|
@ -7111,6 +7101,296 @@
|
|||
"xpack.apm.views.traceOverview.title": "追溯",
|
||||
"xpack.apm.views.transactions.title": "事务",
|
||||
"xpack.apm.waterfall.exceedsMax": "此跟踪中的项目数超过显示的项目数",
|
||||
"xpack.observability.apply.label": "应用",
|
||||
"xpack.observability.search.url.close": "关闭",
|
||||
"xpack.observability.filters.filterByUrl": "按 URL 筛选",
|
||||
"xpack.observability.filters.searchResults": "{total} 项搜索结果",
|
||||
"xpack.observability.filters.select": "选择",
|
||||
"xpack.observability.filters.topPages": "排名靠前页面",
|
||||
"xpack.observability.filters.url": "URL",
|
||||
"xpack.observability.filters.url.loadingResults": "正在加载结果",
|
||||
"xpack.observability.filters.url.noResults": "没有可用结果",
|
||||
"xpack.observability.alerts.manageRulesButtonLabel": "管理规则",
|
||||
"xpack.observability.alerts.searchBarPlaceholder": "kibana.alert.evaluation.threshold > 75",
|
||||
"xpack.observability.alertsDisclaimerLinkText": "告警和操作",
|
||||
"xpack.observability.alertsDisclaimerText": "此页面显示实验性告警视图。此处显示的数据可能无法准确表示告警。在“堆栈管理”的“告警和操作”中提供了告警的非实验性列表。",
|
||||
"xpack.observability.alertsDisclaimerTitle": "实验性",
|
||||
"xpack.observability.alertsFlyout.actualValueLabel": "实际值",
|
||||
"xpack.observability.alertsFlyout.durationLabel": "持续时间",
|
||||
"xpack.observability.alertsFlyout.expectedValueLabel": "预期值",
|
||||
"xpack.observability.alertsFlyout.ruleTypeLabel": "规则类型",
|
||||
"xpack.observability.alertsFlyout.statusLabel": "状态",
|
||||
"xpack.observability.alertsLinkTitle": "告警",
|
||||
"xpack.observability.alertsTable.actionsTextLabel": "操作",
|
||||
"xpack.observability.alertsTable.footerTextLabel": "告警",
|
||||
"xpack.observability.alertsTable.loadingTextLabel": "正在加载告警",
|
||||
"xpack.observability.alertsTable.showingAlertsTitle": "{totalAlerts, plural, other {告警}}",
|
||||
"xpack.observability.alertsTGrid.durationColumnDescription": "持续时间",
|
||||
"xpack.observability.alertsTGrid.lastUpdatedColumnDescription": "上次更新时间",
|
||||
"xpack.observability.alertsTGrid.reasonColumnDescription": "原因",
|
||||
"xpack.observability.alertsTGrid.statusColumnDescription": "状态",
|
||||
"xpack.observability.alertsTitle": "告警",
|
||||
"xpack.observability.breadcrumbs.alertsLinkText": "告警",
|
||||
"xpack.observability.breadcrumbs.casesConfigureLinkText": "配置",
|
||||
"xpack.observability.breadcrumbs.casesCreateLinkText": "创建",
|
||||
"xpack.observability.breadcrumbs.casesLinkText": "案例",
|
||||
"xpack.observability.breadcrumbs.landingLinkText": "入门",
|
||||
"xpack.observability.breadcrumbs.observabilityLinkText": "可观测性",
|
||||
"xpack.observability.breadcrumbs.overviewLinkText": "概览",
|
||||
"xpack.observability.cases.allCases.actions": "操作",
|
||||
"xpack.observability.cases.allCases.comments": "注释",
|
||||
"xpack.observability.cases.allCases.noTagsAvailable": "没有可用标签",
|
||||
"xpack.observability.cases.badge.readOnly.text": "只读",
|
||||
"xpack.observability.cases.badge.readOnly.tooltip": "无法创建或编辑案例",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsMessage": "要查看案例,必须对 Kibana 工作区中的案例功能有权限。有关详细信息,请联系您的 Kibana 管理员。",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsTitle": "需要 Kibana 功能权限",
|
||||
"xpack.observability.cases.caseView.backLabel": "返回到案例",
|
||||
"xpack.observability.cases.caseView.cancel": "取消",
|
||||
"xpack.observability.cases.caseView.caseName": "案例名称",
|
||||
"xpack.observability.cases.caseView.closeCase": "关闭案例",
|
||||
"xpack.observability.cases.caseView.comment.addComment": "添加注释",
|
||||
"xpack.observability.cases.caseView.comment.addCommentHelpText": "添加新注释......",
|
||||
"xpack.observability.cases.caseView.commentFieldRequiredError": "注释必填。",
|
||||
"xpack.observability.cases.caseView.connectors": "外部事件管理系统",
|
||||
"xpack.observability.cases.caseView.create": "创建新案例",
|
||||
"xpack.observability.cases.caseView.createCase": "创建案例",
|
||||
"xpack.observability.cases.caseView.description": "描述",
|
||||
"xpack.observability.cases.caseView.description.save": "保存",
|
||||
"xpack.observability.cases.caseView.edit": "编辑",
|
||||
"xpack.observability.cases.caseView.editConnector": "更改外部事件管理系统",
|
||||
"xpack.observability.cases.caseView.fieldRequiredError": "必填字段",
|
||||
"xpack.observability.cases.caseView.goToDocumentationButton": "查看文档",
|
||||
"xpack.observability.cases.caseView.name": "名称",
|
||||
"xpack.observability.cases.caseView.noReportersAvailable": "没有报告者。",
|
||||
"xpack.observability.cases.caseView.noTags": "当前没有为此案例分配标签。",
|
||||
"xpack.observability.cases.caseView.optional": "可选",
|
||||
"xpack.observability.cases.caseView.particpantsLabel": "参与者",
|
||||
"xpack.observability.cases.caseView.reopenCase": "重新打开案例",
|
||||
"xpack.observability.cases.caseView.reporterLabel": "报告者",
|
||||
"xpack.observability.cases.caseView.tags": "标签",
|
||||
"xpack.observability.cases.caseView.to": "到",
|
||||
"xpack.observability.cases.configureCases.headerTitle": "配置案例",
|
||||
"xpack.observability.cases.configureCasesButton": "编辑外部连接",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCase": "删除案例",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCases": "删除案例",
|
||||
"xpack.observability.cases.createCase.descriptionFieldRequiredError": "描述必填。",
|
||||
"xpack.observability.cases.createCase.fieldTagsHelpText": "为此案例键入一个或多个定制识别标签。在每个标签后按 Enter 键可开始新的标签。",
|
||||
"xpack.observability.cases.createCase.titleFieldRequiredError": "标题必填。",
|
||||
"xpack.observability.cases.dismissErrorsPushServiceCallOutTitle": "关闭",
|
||||
"xpack.observability.cases.pageTitle": "案例",
|
||||
"xpack.observability.casesLinkTitle": "案例",
|
||||
"xpack.observability.emptySection.apps.alert.description": "503 错误是否越来越多?服务是否响应?CPU 和 RAM 利用率是否激增?实时查看警告,而不是事后再进行剖析。",
|
||||
"xpack.observability.emptySection.apps.alert.link": "创建规则",
|
||||
"xpack.observability.emptySection.apps.alert.title": "未找到告警。",
|
||||
"xpack.observability.emptySection.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。",
|
||||
"xpack.observability.emptySection.apps.apm.link": "安装代理",
|
||||
"xpack.observability.emptySection.apps.apm.title": "APM",
|
||||
"xpack.observability.emptySection.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。",
|
||||
"xpack.observability.emptySection.apps.logs.link": "安装 Filebeat",
|
||||
"xpack.observability.emptySection.apps.logs.title": "日志",
|
||||
"xpack.observability.emptySection.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。",
|
||||
"xpack.observability.emptySection.apps.metrics.link": "安装 Metricbeat",
|
||||
"xpack.observability.emptySection.apps.metrics.title": "指标",
|
||||
"xpack.observability.emptySection.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。",
|
||||
"xpack.observability.emptySection.apps.uptime.link": "安装 Heartbeat",
|
||||
"xpack.observability.emptySection.apps.uptime.title": "运行时间",
|
||||
"xpack.observability.emptySection.apps.ux.description": "性能具有分布特征。测量所有访问者的 Web 应用程序访问体验,并了解如何改善每个人的体验。",
|
||||
"xpack.observability.emptySection.apps.ux.link": "安装 RUM 代理",
|
||||
"xpack.observability.emptySection.apps.ux.title": "用户体验",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentDescription": "检查 API 响应中的 Elasticsearch 查询。",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentName": "检查 ES 查询",
|
||||
"xpack.observability.exp.breakDownFilter.noBreakdown": "无细目",
|
||||
"xpack.observability.experimentalBadgeDescription": "此功能为实验性功能,在未来版本中可能会更改或完全移除。Elastic 将尽最大努力来修复任何问题,但实验性功能不受正式 GA 功能支持 SLA 的约束。",
|
||||
"xpack.observability.experimentalBadgeLabel": "实验性",
|
||||
"xpack.observability.exploratoryView.noBrusing": "按画笔选择缩放仅适用于时间序列图表。",
|
||||
"xpack.observability.expView.chartTypes.label": "图表类型",
|
||||
"xpack.observability.expView.columns.label": "{sourceField} 的第 {percentileValue} 百分位",
|
||||
"xpack.observability.expView.columns.operation.label": "{sourceField} 的 {operationType}",
|
||||
"xpack.observability.expView.dateRanger.endDate": "结束日期",
|
||||
"xpack.observability.expView.dateRanger.startDate": "开始日期",
|
||||
"xpack.observability.expView.fieldLabels.agentHost": "代理主机",
|
||||
"xpack.observability.expView.fieldLabels.backend": "后端时间",
|
||||
"xpack.observability.expView.fieldLabels.browserFamily": "浏览器系列",
|
||||
"xpack.observability.expView.fieldLabels.browserVersion": "浏览器版本",
|
||||
"xpack.observability.expView.fieldLabels.carrierLocation": "运营商位置",
|
||||
"xpack.observability.expView.fieldLabels.carrierName": "运营商名称",
|
||||
"xpack.observability.expView.fieldLabels.cls": "累计布局偏移",
|
||||
"xpack.observability.expView.fieldLabels.connectionType": "连接类型",
|
||||
"xpack.observability.expView.fieldLabels.coreWebVitals": "网站体验核心指标",
|
||||
"xpack.observability.expView.fieldLabels.cpuUsage": "CPU 使用率",
|
||||
"xpack.observability.expView.fieldLabels.dcl": "DOM 内容已加载",
|
||||
"xpack.observability.expView.fieldLabels.device": "设备",
|
||||
"xpack.observability.expView.fieldLabels.deviceDistribution": "设备分布",
|
||||
"xpack.observability.expView.fieldLabels.deviceModel": "设备型号",
|
||||
"xpack.observability.expView.fieldLabels.downPings": "关闭 Ping",
|
||||
"xpack.observability.expView.fieldLabels.environment": "环境",
|
||||
"xpack.observability.expView.fieldLabels.fcp": "首次内容绘制",
|
||||
"xpack.observability.expView.fieldLabels.fid": "首次输入延迟",
|
||||
"xpack.observability.expView.fieldLabels.hostName": "主机名",
|
||||
"xpack.observability.expView.fieldLabels.hostOS": "主机 OS",
|
||||
"xpack.observability.expView.fieldLabels.kpi": "KPI",
|
||||
"xpack.observability.expView.fieldLabels.kpiOverTime": "时移 KPI",
|
||||
"xpack.observability.expView.fieldLabels.lcp": "最大内容绘制",
|
||||
"xpack.observability.expView.fieldLabels.location": "位置",
|
||||
"xpack.observability.expView.fieldLabels.memoryUsage": "系统内存使用",
|
||||
"xpack.observability.expView.fieldLabels.metric": "指标",
|
||||
"xpack.observability.expView.fieldLabels.mobile.memoryUsage": "内存利用率",
|
||||
"xpack.observability.expView.fieldLabels.mobileApp": "移动应用",
|
||||
"xpack.observability.expView.fieldLabels.mobileResponse": "移动响应",
|
||||
"xpack.observability.expView.fieldLabels.monitorDurationLabel": "监测持续时间",
|
||||
"xpack.observability.expView.fieldLabels.monitorId": "监测 ID",
|
||||
"xpack.observability.expView.fieldLabels.monitorName": "监测名称",
|
||||
"xpack.observability.expView.fieldLabels.monitorStatus": "监测状态",
|
||||
"xpack.observability.expView.fieldLabels.monitorType": "监测类型",
|
||||
"xpack.observability.expView.fieldLabels.numberOfDevices": "设备数量",
|
||||
"xpack.observability.expView.fieldLabels.obsLocation": "观察者位置",
|
||||
"xpack.observability.expView.fieldLabels.onload": "文档完成 (onLoad)",
|
||||
"xpack.observability.expView.fieldLabels.os": "操作系统",
|
||||
"xpack.observability.expView.fieldLabels.osPlatform": "OS 平台",
|
||||
"xpack.observability.expView.fieldLabels.pageLoadTime": "页面加载时间",
|
||||
"xpack.observability.expView.fieldLabels.pagesLoaded": "已加载页面",
|
||||
"xpack.observability.expView.fieldLabels.pageViews": "页面查看次数",
|
||||
"xpack.observability.expView.fieldLabels.performanceDistribution": "性能分布",
|
||||
"xpack.observability.expView.fieldLabels.pings": "Ping",
|
||||
"xpack.observability.expView.fieldLabels.port": "端口",
|
||||
"xpack.observability.expView.fieldLabels.requestMethod": "请求方法",
|
||||
"xpack.observability.expView.fieldLabels.responseLatency": "延迟",
|
||||
"xpack.observability.expView.fieldLabels.serviceName": "服务名称",
|
||||
"xpack.observability.expView.fieldLabels.serviceVersion": "服务版本",
|
||||
"xpack.observability.expView.fieldLabels.tags": "标签",
|
||||
"xpack.observability.expView.fieldLabels.tbt": "阻止总时间",
|
||||
"xpack.observability.expView.fieldLabels.transactionPerMinute": "吞吐量",
|
||||
"xpack.observability.expView.fieldLabels.upPings": "运行 Ping",
|
||||
"xpack.observability.expView.fieldLabels.url": "URL",
|
||||
"xpack.observability.expView.fieldLabels.webApplication": "Web 应用程序",
|
||||
"xpack.observability.expView.filterValueButton.negate": "不是 {value}",
|
||||
"xpack.observability.expView.heading.experimental": "实验性",
|
||||
"xpack.observability.expView.heading.label": "分析数据",
|
||||
"xpack.observability.expView.heading.openInLens": "在 Lens 中打开",
|
||||
"xpack.observability.expView.heading.saveLensVisualization": "保存",
|
||||
"xpack.observability.expView.operationType.75thPercentile": "第 75 个百分位",
|
||||
"xpack.observability.expView.operationType.90thPercentile": "第 90 个百分位",
|
||||
"xpack.observability.expView.operationType.95thPercentile": "第 95 个百分位",
|
||||
"xpack.observability.expView.operationType.99thPercentile": "第 99 个百分位",
|
||||
"xpack.observability.expView.operationType.average": "平均值",
|
||||
"xpack.observability.expView.operationType.median": "中值",
|
||||
"xpack.observability.expView.operationType.sum": "求和",
|
||||
"xpack.observability.expView.reportType.selectDataType": "选择数据类型以创建可视化。",
|
||||
"xpack.observability.expView.seriesBuilder.addSeries": "添加序列",
|
||||
"xpack.observability.expView.seriesBuilder.apply": "应用更改",
|
||||
"xpack.observability.expView.seriesBuilder.emptyReportDefinition": "选择报告定义以创建可视化。",
|
||||
"xpack.observability.expView.seriesBuilder.emptyview": "没有可显示的内容。",
|
||||
"xpack.observability.expView.seriesBuilder.loadingView": "正在加载视图......",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType": "未选择任何报告类型",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType.empty": "选择报告类型以创建可视化。",
|
||||
"xpack.observability.expView.seriesEditor.clearFilter": "清除筛选",
|
||||
"xpack.observability.expView.seriesEditor.notFound": "未找到任何序列。请添加序列。",
|
||||
"xpack.observability.expView.seriesEditor.removeSeries": "单击移除序列",
|
||||
"xpack.observability.featureCatalogueDescription": "通过专用 UI 整合您的日志、指标、应用程序跟踪和系统可用性。",
|
||||
"xpack.observability.featureCatalogueTitle": "可观测性",
|
||||
"xpack.observability.featureRegistry.linkObservabilityTitle": "案例",
|
||||
"xpack.observability.feedbackMenu.appName": "可观测性",
|
||||
"xpack.observability.fieldValueSelection.apply": "应用",
|
||||
"xpack.observability.fieldValueSelection.loading": "正在加载",
|
||||
"xpack.observability.fieldValueSelection.placeholder": "筛选 {label}",
|
||||
"xpack.observability.fieldValueSelection.placeholder.search": "搜索 {label}",
|
||||
"xpack.observability.filterButton.label": "展开筛选 {label} 的筛选组",
|
||||
"xpack.observability.filters.expanded.noFilter": "未找到任何筛选。",
|
||||
"xpack.observability.filters.expanded.search": "搜索 {label}",
|
||||
"xpack.observability.fleet.button": "试用 Fleet",
|
||||
"xpack.observability.fleet.text": "通过 Elastic 代理,可以简单统一的方式将日志、指标和其他类型数据的监测添加到主机。您无需安装多个 Beats 和其他代理,以令其更为方便快捷地在基础结构中部署配置。",
|
||||
"xpack.observability.fleet.title": "您是否了解我们的全新 Fleet?",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabel": "h",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabelExtended": "小时",
|
||||
"xpack.observability.formatters.microsTimeUnitLabel": "μs",
|
||||
"xpack.observability.formatters.microsTimeUnitLabelExtended": "微秒",
|
||||
"xpack.observability.formatters.millisTimeUnitLabel": "ms",
|
||||
"xpack.observability.formatters.millisTimeUnitLabelExtended": "毫秒",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabel": "最小值",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabelExtended": "分钟",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabel": "s",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒",
|
||||
"xpack.observability.home.addData": "添加数据",
|
||||
"xpack.observability.navigation.newBadge": "新建",
|
||||
"xpack.observability.news.readFullStory": "详细了解",
|
||||
"xpack.observability.news.title": "最新动态",
|
||||
"xpack.observability.notAvailable": "不可用",
|
||||
"xpack.observability.overview.alert.allTypes": "所有类型",
|
||||
"xpack.observability.overview.alert.appLink": "管理告警",
|
||||
"xpack.observability.overview.alerts.muted": "已静音",
|
||||
"xpack.observability.overview.alerts.title": "告警",
|
||||
"xpack.observability.overview.apm.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.apm.services": "服务",
|
||||
"xpack.observability.overview.apm.throughput": "吞吐量",
|
||||
"xpack.observability.overview.apm.title": "APM",
|
||||
"xpack.observability.overview.exploratoryView": "分析数据",
|
||||
"xpack.observability.overview.exploratoryView.lensDisabled": "Lens 应用不可用,请启用 Lens 以使用浏览视图。",
|
||||
"xpack.observability.overview.loadingObservability": "正在加载可观测性",
|
||||
"xpack.observability.overview.logs.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.logs.subtitle": "每分钟日志速率",
|
||||
"xpack.observability.overview.logs.title": "日志",
|
||||
"xpack.observability.overview.metrics.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.metrics.colunms.cpu": "CPU %",
|
||||
"xpack.observability.overview.metrics.colunms.hostname": "主机名",
|
||||
"xpack.observability.overview.metrics.colunms.load15": "加载 15",
|
||||
"xpack.observability.overview.metrics.colunms.uptime": "运行时间",
|
||||
"xpack.observability.overview.metrics.title": "指标",
|
||||
"xpack.observability.overview.pageTitle": "概览",
|
||||
"xpack.observability.overview.uptime.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.uptime.chart.down": "关闭",
|
||||
"xpack.observability.overview.uptime.chart.up": "运行",
|
||||
"xpack.observability.overview.uptime.down": "关闭",
|
||||
"xpack.observability.overview.uptime.monitors": "监测",
|
||||
"xpack.observability.overview.uptime.title": "运行时间",
|
||||
"xpack.observability.overview.uptime.up": "运行",
|
||||
"xpack.observability.overview.ux.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.ux.title": "用户体验",
|
||||
"xpack.observability.overviewLinkTitle": "概览",
|
||||
"xpack.observability.pageLayout.sideNavTitle": "可观测性",
|
||||
"xpack.observability.resources.documentation": "文档",
|
||||
"xpack.observability.resources.forum": "讨论论坛",
|
||||
"xpack.observability.resources.quick_start": "快速入门视频",
|
||||
"xpack.observability.resources.title": "资源",
|
||||
"xpack.observability.resources.training": "免费的可观测性课程",
|
||||
"xpack.observability.section.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。",
|
||||
"xpack.observability.section.apps.apm.title": "APM",
|
||||
"xpack.observability.section.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。",
|
||||
"xpack.observability.section.apps.logs.title": "日志",
|
||||
"xpack.observability.section.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。",
|
||||
"xpack.observability.section.apps.metrics.title": "指标",
|
||||
"xpack.observability.section.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。",
|
||||
"xpack.observability.section.apps.uptime.title": "运行时间",
|
||||
"xpack.observability.section.errorPanel": "尝试提取数据时发生错误。请重试",
|
||||
"xpack.observability.seriesEditor.clone": "复制序列",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.ux.coreVitals.average": "平均值",
|
||||
"xpack.observability.ux.coreVitals.averageMessage": " 且小于 {bad}",
|
||||
"xpack.observability.ux.coreVitals.cls": "累计布局偏移",
|
||||
"xpack.observability.ux.coreVitals.cls.help": "累计布局偏移 (CLS):衡量视觉稳定性。为了提供良好的用户体验,页面的 CLS 应小于 0.1。",
|
||||
"xpack.observability.ux.coreVitals.fid.help": "首次输入延迟用于衡量交互性。为了提供良好的用户体验,页面的 FID 应小于 100 毫秒。",
|
||||
"xpack.observability.ux.coreVitals.fip": "首次输入延迟",
|
||||
"xpack.observability.ux.coreVitals.good": "良好",
|
||||
"xpack.observability.ux.coreVitals.is": "是",
|
||||
"xpack.observability.ux.coreVitals.lcp": "最大内容绘制",
|
||||
"xpack.observability.ux.coreVitals.lcp.help": "最大内容绘制用于衡量加载性能。为了提供良好的用户体验,LCP 应在页面首次开始加载后的 2.5 秒内执行。",
|
||||
"xpack.observability.ux.coreVitals.legends.good": "良",
|
||||
"xpack.observability.ux.coreVitals.legends.needsImprovement": "需改进",
|
||||
"xpack.observability.ux.coreVitals.legends.poor": "差",
|
||||
"xpack.observability.ux.coreVitals.less": "更少",
|
||||
"xpack.observability.ux.coreVitals.more": "更多",
|
||||
"xpack.observability.ux.coreVitals.noData": "没有可用数据。",
|
||||
"xpack.observability.ux.coreVitals.paletteLegend.rankPercentage": "{labelsInd} ({ranksInd}%)",
|
||||
"xpack.observability.ux.coreVitals.poor": "不良",
|
||||
"xpack.observability.ux.coreVitals.takes": "需要",
|
||||
"xpack.observability.ux.coreWebVitals": "网站体验核心指标",
|
||||
"xpack.observability.ux.coreWebVitals.browser.support": "浏览器对网站体验核心指标的支持",
|
||||
"xpack.observability.ux.coreWebVitals.service": "服务",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.browser.help": "详细了解",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.help": "详细了解",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "帮助",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.traffic": "已占 {trafficPerc} 的流量",
|
||||
"xpack.observability.ux.dashboard.webVitals.palette.tooltip": "{percentage}% 的用户具有{exp }体验,因为 {title} {isOrTakes} {moreOrLess}于 {value}{averageMessage}。",
|
||||
"xpack.observability.ux.service.help": "选择流量最高的 RUM 服务",
|
||||
"xpack.banners.settings.backgroundColor.description": "设置横幅广告的背景色。{subscriptionLink}",
|
||||
"xpack.banners.settings.backgroundColor.title": "横幅广告背景色",
|
||||
"xpack.banners.settings.placement.description": "在 Elastic 页眉上显示此工作区的顶部横幅广告。{subscriptionLink}",
|
||||
|
@ -19011,287 +19291,6 @@
|
|||
"xpack.monitoring.updateLicenseButtonLabel": "更新许可证",
|
||||
"xpack.monitoring.updateLicenseTitle": "更新您的许可证",
|
||||
"xpack.monitoring.useAvailableLicenseDescription": "如果您已经持有新的许可证,请立即上传。",
|
||||
"xpack.observability.alerts.manageRulesButtonLabel": "管理规则",
|
||||
"xpack.observability.alerts.searchBarPlaceholder": "kibana.alert.evaluation.threshold > 75",
|
||||
"xpack.observability.alertsDisclaimerLinkText": "告警和操作",
|
||||
"xpack.observability.alertsDisclaimerText": "此页面显示实验性告警视图。此处显示的数据可能无法准确表示告警。在“堆栈管理”的“告警和操作”中提供了告警的非实验性列表。",
|
||||
"xpack.observability.alertsDisclaimerTitle": "实验性",
|
||||
"xpack.observability.alertsFlyout.actualValueLabel": "实际值",
|
||||
"xpack.observability.alertsFlyout.durationLabel": "持续时间",
|
||||
"xpack.observability.alertsFlyout.expectedValueLabel": "预期值",
|
||||
"xpack.observability.alertsFlyout.ruleTypeLabel": "规则类型",
|
||||
"xpack.observability.alertsFlyout.statusLabel": "状态",
|
||||
"xpack.observability.alertsLinkTitle": "告警",
|
||||
"xpack.observability.alertsTable.actionsTextLabel": "操作",
|
||||
"xpack.observability.alertsTable.footerTextLabel": "告警",
|
||||
"xpack.observability.alertsTable.loadingTextLabel": "正在加载告警",
|
||||
"xpack.observability.alertsTable.showingAlertsTitle": "{totalAlerts, plural, other {告警}}",
|
||||
"xpack.observability.alertsTGrid.durationColumnDescription": "持续时间",
|
||||
"xpack.observability.alertsTGrid.lastUpdatedColumnDescription": "上次更新时间",
|
||||
"xpack.observability.alertsTGrid.reasonColumnDescription": "原因",
|
||||
"xpack.observability.alertsTGrid.statusColumnDescription": "状态",
|
||||
"xpack.observability.alertsTitle": "告警",
|
||||
"xpack.observability.breadcrumbs.alertsLinkText": "告警",
|
||||
"xpack.observability.breadcrumbs.casesConfigureLinkText": "配置",
|
||||
"xpack.observability.breadcrumbs.casesCreateLinkText": "创建",
|
||||
"xpack.observability.breadcrumbs.casesLinkText": "案例",
|
||||
"xpack.observability.breadcrumbs.landingLinkText": "入门",
|
||||
"xpack.observability.breadcrumbs.observabilityLinkText": "可观测性",
|
||||
"xpack.observability.breadcrumbs.overviewLinkText": "概览",
|
||||
"xpack.observability.cases.allCases.actions": "操作",
|
||||
"xpack.observability.cases.allCases.comments": "注释",
|
||||
"xpack.observability.cases.allCases.noTagsAvailable": "没有可用标签",
|
||||
"xpack.observability.cases.badge.readOnly.text": "只读",
|
||||
"xpack.observability.cases.badge.readOnly.tooltip": "无法创建或编辑案例",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsMessage": "要查看案例,必须对 Kibana 工作区中的案例功能有权限。有关详细信息,请联系您的 Kibana 管理员。",
|
||||
"xpack.observability.cases.caseFeatureNoPermissionsTitle": "需要 Kibana 功能权限",
|
||||
"xpack.observability.cases.caseView.backLabel": "返回到案例",
|
||||
"xpack.observability.cases.caseView.cancel": "取消",
|
||||
"xpack.observability.cases.caseView.caseName": "案例名称",
|
||||
"xpack.observability.cases.caseView.closeCase": "关闭案例",
|
||||
"xpack.observability.cases.caseView.comment.addComment": "添加注释",
|
||||
"xpack.observability.cases.caseView.comment.addCommentHelpText": "添加新注释......",
|
||||
"xpack.observability.cases.caseView.commentFieldRequiredError": "注释必填。",
|
||||
"xpack.observability.cases.caseView.connectors": "外部事件管理系统",
|
||||
"xpack.observability.cases.caseView.create": "创建新案例",
|
||||
"xpack.observability.cases.caseView.createCase": "创建案例",
|
||||
"xpack.observability.cases.caseView.description": "描述",
|
||||
"xpack.observability.cases.caseView.description.save": "保存",
|
||||
"xpack.observability.cases.caseView.edit": "编辑",
|
||||
"xpack.observability.cases.caseView.editConnector": "更改外部事件管理系统",
|
||||
"xpack.observability.cases.caseView.fieldRequiredError": "必填字段",
|
||||
"xpack.observability.cases.caseView.goToDocumentationButton": "查看文档",
|
||||
"xpack.observability.cases.caseView.name": "名称",
|
||||
"xpack.observability.cases.caseView.noReportersAvailable": "没有报告者。",
|
||||
"xpack.observability.cases.caseView.noTags": "当前没有为此案例分配标签。",
|
||||
"xpack.observability.cases.caseView.optional": "可选",
|
||||
"xpack.observability.cases.caseView.particpantsLabel": "参与者",
|
||||
"xpack.observability.cases.caseView.reopenCase": "重新打开案例",
|
||||
"xpack.observability.cases.caseView.reporterLabel": "报告者",
|
||||
"xpack.observability.cases.caseView.tags": "标签",
|
||||
"xpack.observability.cases.caseView.to": "到",
|
||||
"xpack.observability.cases.configureCases.headerTitle": "配置案例",
|
||||
"xpack.observability.cases.configureCasesButton": "编辑外部连接",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCase": "删除案例",
|
||||
"xpack.observability.cases.confirmDeleteCase.deleteCases": "删除案例",
|
||||
"xpack.observability.cases.createCase.descriptionFieldRequiredError": "描述必填。",
|
||||
"xpack.observability.cases.createCase.fieldTagsHelpText": "为此案例键入一个或多个定制识别标签。在每个标签后按 Enter 键可开始新的标签。",
|
||||
"xpack.observability.cases.createCase.titleFieldRequiredError": "标题必填。",
|
||||
"xpack.observability.cases.dismissErrorsPushServiceCallOutTitle": "关闭",
|
||||
"xpack.observability.cases.pageTitle": "案例",
|
||||
"xpack.observability.casesLinkTitle": "案例",
|
||||
"xpack.observability.emptySection.apps.alert.description": "503 错误是否越来越多?服务是否响应?CPU 和 RAM 利用率是否激增?实时查看警告,而不是事后再进行剖析。",
|
||||
"xpack.observability.emptySection.apps.alert.link": "创建规则",
|
||||
"xpack.observability.emptySection.apps.alert.title": "未找到告警。",
|
||||
"xpack.observability.emptySection.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。",
|
||||
"xpack.observability.emptySection.apps.apm.link": "安装代理",
|
||||
"xpack.observability.emptySection.apps.apm.title": "APM",
|
||||
"xpack.observability.emptySection.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。",
|
||||
"xpack.observability.emptySection.apps.logs.link": "安装 Filebeat",
|
||||
"xpack.observability.emptySection.apps.logs.title": "日志",
|
||||
"xpack.observability.emptySection.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。",
|
||||
"xpack.observability.emptySection.apps.metrics.link": "安装 Metricbeat",
|
||||
"xpack.observability.emptySection.apps.metrics.title": "指标",
|
||||
"xpack.observability.emptySection.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。",
|
||||
"xpack.observability.emptySection.apps.uptime.link": "安装 Heartbeat",
|
||||
"xpack.observability.emptySection.apps.uptime.title": "运行时间",
|
||||
"xpack.observability.emptySection.apps.ux.description": "性能具有分布特征。测量所有访问者的 Web 应用程序访问体验,并了解如何改善每个人的体验。",
|
||||
"xpack.observability.emptySection.apps.ux.link": "安装 RUM 代理",
|
||||
"xpack.observability.emptySection.apps.ux.title": "用户体验",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentDescription": "检查 API 响应中的 Elasticsearch 查询。",
|
||||
"xpack.observability.enableInspectEsQueriesExperimentName": "检查 ES 查询",
|
||||
"xpack.observability.exp.breakDownFilter.noBreakdown": "无细目",
|
||||
"xpack.observability.experimentalBadgeDescription": "此功能为实验性功能,在未来版本中可能会更改或完全移除。Elastic 将尽最大努力来修复任何问题,但实验性功能不受正式 GA 功能支持 SLA 的约束。",
|
||||
"xpack.observability.experimentalBadgeLabel": "实验性",
|
||||
"xpack.observability.exploratoryView.noBrusing": "按画笔选择缩放仅适用于时间序列图表。",
|
||||
"xpack.observability.expView.chartTypes.label": "图表类型",
|
||||
"xpack.observability.expView.columns.label": "{sourceField} 的第 {percentileValue} 百分位",
|
||||
"xpack.observability.expView.columns.operation.label": "{sourceField} 的 {operationType}",
|
||||
"xpack.observability.expView.dateRanger.endDate": "结束日期",
|
||||
"xpack.observability.expView.dateRanger.startDate": "开始日期",
|
||||
"xpack.observability.expView.fieldLabels.agentHost": "代理主机",
|
||||
"xpack.observability.expView.fieldLabels.backend": "后端时间",
|
||||
"xpack.observability.expView.fieldLabels.browserFamily": "浏览器系列",
|
||||
"xpack.observability.expView.fieldLabels.browserVersion": "浏览器版本",
|
||||
"xpack.observability.expView.fieldLabels.carrierLocation": "运营商位置",
|
||||
"xpack.observability.expView.fieldLabels.carrierName": "运营商名称",
|
||||
"xpack.observability.expView.fieldLabels.cls": "累计布局偏移",
|
||||
"xpack.observability.expView.fieldLabels.connectionType": "连接类型",
|
||||
"xpack.observability.expView.fieldLabels.coreWebVitals": "网站体验核心指标",
|
||||
"xpack.observability.expView.fieldLabels.cpuUsage": "CPU 使用率",
|
||||
"xpack.observability.expView.fieldLabels.dcl": "DOM 内容已加载",
|
||||
"xpack.observability.expView.fieldLabels.device": "设备",
|
||||
"xpack.observability.expView.fieldLabels.deviceDistribution": "设备分布",
|
||||
"xpack.observability.expView.fieldLabels.deviceModel": "设备型号",
|
||||
"xpack.observability.expView.fieldLabels.downPings": "关闭 Ping",
|
||||
"xpack.observability.expView.fieldLabels.environment": "环境",
|
||||
"xpack.observability.expView.fieldLabels.fcp": "首次内容绘制",
|
||||
"xpack.observability.expView.fieldLabels.fid": "首次输入延迟",
|
||||
"xpack.observability.expView.fieldLabels.hostName": "主机名",
|
||||
"xpack.observability.expView.fieldLabels.hostOS": "主机 OS",
|
||||
"xpack.observability.expView.fieldLabels.kpi": "KPI",
|
||||
"xpack.observability.expView.fieldLabels.kpiOverTime": "时移 KPI",
|
||||
"xpack.observability.expView.fieldLabels.lcp": "最大内容绘制",
|
||||
"xpack.observability.expView.fieldLabels.location": "位置",
|
||||
"xpack.observability.expView.fieldLabels.memoryUsage": "系统内存使用",
|
||||
"xpack.observability.expView.fieldLabels.metric": "指标",
|
||||
"xpack.observability.expView.fieldLabels.mobile.memoryUsage": "内存利用率",
|
||||
"xpack.observability.expView.fieldLabels.mobileApp": "移动应用",
|
||||
"xpack.observability.expView.fieldLabels.mobileResponse": "移动响应",
|
||||
"xpack.observability.expView.fieldLabels.monitorDurationLabel": "监测持续时间",
|
||||
"xpack.observability.expView.fieldLabels.monitorId": "监测 ID",
|
||||
"xpack.observability.expView.fieldLabels.monitorName": "监测名称",
|
||||
"xpack.observability.expView.fieldLabels.monitorStatus": "监测状态",
|
||||
"xpack.observability.expView.fieldLabels.monitorType": "监测类型",
|
||||
"xpack.observability.expView.fieldLabels.numberOfDevices": "设备数量",
|
||||
"xpack.observability.expView.fieldLabels.obsLocation": "观察者位置",
|
||||
"xpack.observability.expView.fieldLabels.onload": "文档完成 (onLoad)",
|
||||
"xpack.observability.expView.fieldLabels.os": "操作系统",
|
||||
"xpack.observability.expView.fieldLabels.osPlatform": "OS 平台",
|
||||
"xpack.observability.expView.fieldLabels.pageLoadTime": "页面加载时间",
|
||||
"xpack.observability.expView.fieldLabels.pagesLoaded": "已加载页面",
|
||||
"xpack.observability.expView.fieldLabels.pageViews": "页面查看次数",
|
||||
"xpack.observability.expView.fieldLabels.performanceDistribution": "性能分布",
|
||||
"xpack.observability.expView.fieldLabels.pings": "Ping",
|
||||
"xpack.observability.expView.fieldLabels.port": "端口",
|
||||
"xpack.observability.expView.fieldLabels.requestMethod": "请求方法",
|
||||
"xpack.observability.expView.fieldLabels.responseLatency": "延迟",
|
||||
"xpack.observability.expView.fieldLabels.serviceName": "服务名称",
|
||||
"xpack.observability.expView.fieldLabels.serviceVersion": "服务版本",
|
||||
"xpack.observability.expView.fieldLabels.tags": "标签",
|
||||
"xpack.observability.expView.fieldLabels.tbt": "阻止总时间",
|
||||
"xpack.observability.expView.fieldLabels.transactionPerMinute": "吞吐量",
|
||||
"xpack.observability.expView.fieldLabels.upPings": "运行 Ping",
|
||||
"xpack.observability.expView.fieldLabels.url": "URL",
|
||||
"xpack.observability.expView.fieldLabels.webApplication": "Web 应用程序",
|
||||
"xpack.observability.expView.filterValueButton.negate": "不是 {value}",
|
||||
"xpack.observability.expView.heading.experimental": "实验性",
|
||||
"xpack.observability.expView.heading.label": "分析数据",
|
||||
"xpack.observability.expView.heading.openInLens": "在 Lens 中打开",
|
||||
"xpack.observability.expView.heading.saveLensVisualization": "保存",
|
||||
"xpack.observability.expView.operationType.75thPercentile": "第 75 个百分位",
|
||||
"xpack.observability.expView.operationType.90thPercentile": "第 90 个百分位",
|
||||
"xpack.observability.expView.operationType.95thPercentile": "第 95 个百分位",
|
||||
"xpack.observability.expView.operationType.99thPercentile": "第 99 个百分位",
|
||||
"xpack.observability.expView.operationType.average": "平均值",
|
||||
"xpack.observability.expView.operationType.median": "中值",
|
||||
"xpack.observability.expView.operationType.sum": "求和",
|
||||
"xpack.observability.expView.reportType.selectDataType": "选择数据类型以创建可视化。",
|
||||
"xpack.observability.expView.seriesBuilder.addSeries": "添加序列",
|
||||
"xpack.observability.expView.seriesBuilder.apply": "应用更改",
|
||||
"xpack.observability.expView.seriesBuilder.emptyReportDefinition": "选择报告定义以创建可视化。",
|
||||
"xpack.observability.expView.seriesBuilder.emptyview": "没有可显示的内容。",
|
||||
"xpack.observability.expView.seriesBuilder.loadingView": "正在加载视图......",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType": "未选择任何报告类型",
|
||||
"xpack.observability.expView.seriesBuilder.selectReportType.empty": "选择报告类型以创建可视化。",
|
||||
"xpack.observability.expView.seriesEditor.clearFilter": "清除筛选",
|
||||
"xpack.observability.expView.seriesEditor.notFound": "未找到任何序列。请添加序列。",
|
||||
"xpack.observability.expView.seriesEditor.removeSeries": "单击移除序列",
|
||||
"xpack.observability.featureCatalogueDescription": "通过专用 UI 整合您的日志、指标、应用程序跟踪和系统可用性。",
|
||||
"xpack.observability.featureCatalogueTitle": "可观测性",
|
||||
"xpack.observability.featureRegistry.linkObservabilityTitle": "案例",
|
||||
"xpack.observability.feedbackMenu.appName": "可观测性",
|
||||
"xpack.observability.fieldValueSelection.apply": "应用",
|
||||
"xpack.observability.fieldValueSelection.loading": "正在加载",
|
||||
"xpack.observability.fieldValueSelection.placeholder": "筛选 {label}",
|
||||
"xpack.observability.fieldValueSelection.placeholder.search": "搜索 {label}",
|
||||
"xpack.observability.filterButton.label": "展开筛选 {label} 的筛选组",
|
||||
"xpack.observability.filters.expanded.noFilter": "未找到任何筛选。",
|
||||
"xpack.observability.filters.expanded.search": "搜索 {label}",
|
||||
"xpack.observability.fleet.button": "试用 Fleet",
|
||||
"xpack.observability.fleet.text": "通过 Elastic 代理,可以简单统一的方式将日志、指标和其他类型数据的监测添加到主机。您无需安装多个 Beats 和其他代理,以令其更为方便快捷地在基础结构中部署配置。",
|
||||
"xpack.observability.fleet.title": "您是否了解我们的全新 Fleet?",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabel": "h",
|
||||
"xpack.observability.formatters.hoursTimeUnitLabelExtended": "小时",
|
||||
"xpack.observability.formatters.microsTimeUnitLabel": "μs",
|
||||
"xpack.observability.formatters.microsTimeUnitLabelExtended": "微秒",
|
||||
"xpack.observability.formatters.millisTimeUnitLabel": "ms",
|
||||
"xpack.observability.formatters.millisTimeUnitLabelExtended": "毫秒",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabel": "最小值",
|
||||
"xpack.observability.formatters.minutesTimeUnitLabelExtended": "分钟",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabel": "s",
|
||||
"xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒",
|
||||
"xpack.observability.home.addData": "添加数据",
|
||||
"xpack.observability.navigation.newBadge": "新建",
|
||||
"xpack.observability.news.readFullStory": "详细了解",
|
||||
"xpack.observability.news.title": "最新动态",
|
||||
"xpack.observability.notAvailable": "不可用",
|
||||
"xpack.observability.overview.alert.allTypes": "所有类型",
|
||||
"xpack.observability.overview.alert.appLink": "管理告警",
|
||||
"xpack.observability.overview.alerts.muted": "已静音",
|
||||
"xpack.observability.overview.alerts.title": "告警",
|
||||
"xpack.observability.overview.apm.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.apm.services": "服务",
|
||||
"xpack.observability.overview.apm.throughput": "吞吐量",
|
||||
"xpack.observability.overview.apm.title": "APM",
|
||||
"xpack.observability.overview.exploratoryView": "分析数据",
|
||||
"xpack.observability.overview.exploratoryView.lensDisabled": "Lens 应用不可用,请启用 Lens 以使用浏览视图。",
|
||||
"xpack.observability.overview.loadingObservability": "正在加载可观测性",
|
||||
"xpack.observability.overview.logs.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.logs.subtitle": "每分钟日志速率",
|
||||
"xpack.observability.overview.logs.title": "日志",
|
||||
"xpack.observability.overview.metrics.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.metrics.colunms.cpu": "CPU %",
|
||||
"xpack.observability.overview.metrics.colunms.hostname": "主机名",
|
||||
"xpack.observability.overview.metrics.colunms.load15": "加载 15",
|
||||
"xpack.observability.overview.metrics.colunms.uptime": "运行时间",
|
||||
"xpack.observability.overview.metrics.title": "指标",
|
||||
"xpack.observability.overview.pageTitle": "概览",
|
||||
"xpack.observability.overview.uptime.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.uptime.chart.down": "关闭",
|
||||
"xpack.observability.overview.uptime.chart.up": "运行",
|
||||
"xpack.observability.overview.uptime.down": "关闭",
|
||||
"xpack.observability.overview.uptime.monitors": "监测",
|
||||
"xpack.observability.overview.uptime.title": "运行时间",
|
||||
"xpack.observability.overview.uptime.up": "运行",
|
||||
"xpack.observability.overview.ux.appLink": "在应用中查看",
|
||||
"xpack.observability.overview.ux.title": "用户体验",
|
||||
"xpack.observability.overviewLinkTitle": "概览",
|
||||
"xpack.observability.pageLayout.sideNavTitle": "可观测性",
|
||||
"xpack.observability.resources.documentation": "文档",
|
||||
"xpack.observability.resources.forum": "讨论论坛",
|
||||
"xpack.observability.resources.quick_start": "快速入门视频",
|
||||
"xpack.observability.resources.title": "资源",
|
||||
"xpack.observability.resources.training": "免费的可观测性课程",
|
||||
"xpack.observability.section.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。",
|
||||
"xpack.observability.section.apps.apm.title": "APM",
|
||||
"xpack.observability.section.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。",
|
||||
"xpack.observability.section.apps.logs.title": "日志",
|
||||
"xpack.observability.section.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。",
|
||||
"xpack.observability.section.apps.metrics.title": "指标",
|
||||
"xpack.observability.section.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。",
|
||||
"xpack.observability.section.apps.uptime.title": "运行时间",
|
||||
"xpack.observability.section.errorPanel": "尝试提取数据时发生错误。请重试",
|
||||
"xpack.observability.seriesEditor.clone": "复制序列",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.ux.coreVitals.average": "平均值",
|
||||
"xpack.observability.ux.coreVitals.averageMessage": " 且小于 {bad}",
|
||||
"xpack.observability.ux.coreVitals.cls": "累计布局偏移",
|
||||
"xpack.observability.ux.coreVitals.cls.help": "累计布局偏移 (CLS):衡量视觉稳定性。为了提供良好的用户体验,页面的 CLS 应小于 0.1。",
|
||||
"xpack.observability.ux.coreVitals.fid.help": "首次输入延迟用于衡量交互性。为了提供良好的用户体验,页面的 FID 应小于 100 毫秒。",
|
||||
"xpack.observability.ux.coreVitals.fip": "首次输入延迟",
|
||||
"xpack.observability.ux.coreVitals.good": "良好",
|
||||
"xpack.observability.ux.coreVitals.is": "是",
|
||||
"xpack.observability.ux.coreVitals.lcp": "最大内容绘制",
|
||||
"xpack.observability.ux.coreVitals.lcp.help": "最大内容绘制用于衡量加载性能。为了提供良好的用户体验,LCP 应在页面首次开始加载后的 2.5 秒内执行。",
|
||||
"xpack.observability.ux.coreVitals.legends.good": "良",
|
||||
"xpack.observability.ux.coreVitals.legends.needsImprovement": "需改进",
|
||||
"xpack.observability.ux.coreVitals.legends.poor": "差",
|
||||
"xpack.observability.ux.coreVitals.less": "更少",
|
||||
"xpack.observability.ux.coreVitals.more": "更多",
|
||||
"xpack.observability.ux.coreVitals.noData": "没有可用数据。",
|
||||
"xpack.observability.ux.coreVitals.paletteLegend.rankPercentage": "{labelsInd} ({ranksInd}%)",
|
||||
"xpack.observability.ux.coreVitals.poor": "不良",
|
||||
"xpack.observability.ux.coreVitals.takes": "需要",
|
||||
"xpack.observability.ux.coreWebVitals": "网站体验核心指标",
|
||||
"xpack.observability.ux.coreWebVitals.browser.support": "浏览器对网站体验核心指标的支持",
|
||||
"xpack.observability.ux.coreWebVitals.service": "服务",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.browser.help": "详细了解",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.help": "详细了解",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel": "帮助",
|
||||
"xpack.observability.ux.dashboard.webCoreVitals.traffic": "已占 {trafficPerc} 的流量",
|
||||
"xpack.observability.ux.dashboard.webVitals.palette.tooltip": "{percentage}% 的用户具有{exp }体验,因为 {title} {isOrTakes} {moreOrLess}于 {value}{averageMessage}。",
|
||||
"xpack.observability.ux.service.help": "选择流量最高的 RUM 服务",
|
||||
"xpack.osquery.action_details.fetchError": "提取操作详情时出错",
|
||||
"xpack.osquery.action_policy_details.fetchError": "提取策略详情时出错",
|
||||
"xpack.osquery.action_results.errorSearchDescription": "搜索操作结果时发生错误",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue