mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[UnifiedSearch] Add explore matching indices to data view menu (#141807)
* add explore matching index * adjust type * move things around * fix types * fix tests * fix imports * fix limit * do not clean datasource on adding ad hoc data view Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
parent
2d8eb0eed6
commit
b885d9381d
30 changed files with 308 additions and 137 deletions
|
@ -23,7 +23,7 @@ pageLoadAssetSize:
|
|||
dataViewEditor: 12000
|
||||
dataViewFieldEditor: 27000
|
||||
dataViewManagement: 5000
|
||||
dataViews: 44532
|
||||
dataViews: 46532
|
||||
dataVisualizer: 27530
|
||||
devTools: 38637
|
||||
discover: 99999
|
||||
|
|
|
@ -10,7 +10,12 @@ import React, { useState, useEffect, useCallback, useRef } from 'react';
|
|||
import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import memoizeOne from 'memoize-one';
|
||||
import { DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import {
|
||||
DataViewField,
|
||||
DataViewsPublicPluginStart,
|
||||
INDEX_PATTERN_TYPE,
|
||||
MatchedItem,
|
||||
} from '@kbn/data-views-plugin/public';
|
||||
|
||||
import {
|
||||
DataView,
|
||||
|
@ -23,16 +28,14 @@ import {
|
|||
UseField,
|
||||
} from '../shared_imports';
|
||||
|
||||
import { ensureMinimumTime, getIndices, extractTimeFields, getMatchedIndices } from '../lib';
|
||||
import { ensureMinimumTime, extractTimeFields, getMatchedIndices } from '../lib';
|
||||
import { FlyoutPanels } from './flyout_panels';
|
||||
|
||||
import { removeSpaces } from '../lib';
|
||||
|
||||
import {
|
||||
MatchedItem,
|
||||
DataViewEditorContext,
|
||||
RollupIndicesCapsResponse,
|
||||
INDEX_PATTERN_TYPE,
|
||||
IndexPatternConfig,
|
||||
MatchedIndicesSet,
|
||||
FormInternal,
|
||||
|
@ -176,18 +179,19 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
|
||||
// load all data sources and set initial matchedIndices
|
||||
const loadSources = useCallback(() => {
|
||||
getIndices({
|
||||
http,
|
||||
isRollupIndex: () => false,
|
||||
pattern: '*',
|
||||
showAllIndices: allowHidden,
|
||||
}).then((dataSources) => {
|
||||
setAllSources(dataSources);
|
||||
const matchedSet = getMatchedIndices(dataSources, [], [], allowHidden);
|
||||
setMatchedIndices(matchedSet);
|
||||
setIsLoadingSources(false);
|
||||
});
|
||||
}, [http, allowHidden]);
|
||||
dataViews
|
||||
.getIndices({
|
||||
isRollupIndex: () => false,
|
||||
pattern: '*',
|
||||
showAllIndices: allowHidden,
|
||||
})
|
||||
.then((dataSources) => {
|
||||
setAllSources(dataSources);
|
||||
const matchedSet = getMatchedIndices(dataSources, [], [], allowHidden);
|
||||
setMatchedIndices(matchedSet);
|
||||
setIsLoadingSources(false);
|
||||
});
|
||||
}, [allowHidden, dataViews]);
|
||||
|
||||
// loading list of index patterns
|
||||
useEffect(() => {
|
||||
|
@ -271,7 +275,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
const { matchedIndicesResult, exactMatched } = !isLoadingSources
|
||||
? await loadMatchedIndices(query, allowHidden, allSources, {
|
||||
isRollupIndex,
|
||||
http,
|
||||
dataViews,
|
||||
})
|
||||
: {
|
||||
matchedIndicesResult: {
|
||||
|
@ -302,7 +306,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
|
||||
return fetchIndices(newTitle);
|
||||
},
|
||||
[http, allowHidden, allSources, type, rollupIndicesCapabilities, isLoadingSources]
|
||||
[dataViews, allowHidden, allSources, type, rollupIndicesCapabilities, isLoadingSources]
|
||||
);
|
||||
|
||||
// If editData exists, loadSources so that MatchedIndices can be loaded for the Timestampfields
|
||||
|
@ -453,10 +457,10 @@ const loadMatchedIndices = memoizeOne(
|
|||
allSources: MatchedItem[],
|
||||
{
|
||||
isRollupIndex,
|
||||
http,
|
||||
dataViews,
|
||||
}: {
|
||||
isRollupIndex: (index: string) => boolean;
|
||||
http: DataViewEditorContext['http'];
|
||||
dataViews: DataViewsPublicPluginStart;
|
||||
}
|
||||
): Promise<{
|
||||
matchedIndicesResult: MatchedIndicesSet;
|
||||
|
@ -466,8 +470,7 @@ const loadMatchedIndices = memoizeOne(
|
|||
const indexRequests = [];
|
||||
|
||||
if (query?.endsWith('*')) {
|
||||
const exactMatchedQuery = getIndices({
|
||||
http,
|
||||
const exactMatchedQuery = dataViews.getIndices({
|
||||
isRollupIndex,
|
||||
pattern: query,
|
||||
showAllIndices: allowHidden,
|
||||
|
@ -476,14 +479,12 @@ const loadMatchedIndices = memoizeOne(
|
|||
// provide default value when not making a request for the partialMatchQuery
|
||||
indexRequests.push(Promise.resolve([]));
|
||||
} else {
|
||||
const exactMatchQuery = getIndices({
|
||||
http,
|
||||
const exactMatchQuery = dataViews.getIndices({
|
||||
isRollupIndex,
|
||||
pattern: query,
|
||||
showAllIndices: allowHidden,
|
||||
});
|
||||
const partialMatchQuery = getIndices({
|
||||
http,
|
||||
const partialMatchQuery = dataViews.getIndices({
|
||||
isRollupIndex,
|
||||
pattern: `${query}*`,
|
||||
showAllIndices: allowHidden,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import React, { ChangeEvent, useState, useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiFormRow, EuiFieldText } from '@elastic/eui';
|
||||
import { MatchedItem } from '@kbn/data-views-plugin/public';
|
||||
import {
|
||||
UseField,
|
||||
getFieldValidityAndErrorMessage,
|
||||
|
@ -17,12 +18,7 @@ import {
|
|||
} from '../../shared_imports';
|
||||
import { canAppendWildcard, removeSpaces } from '../../lib';
|
||||
import { schema } from '../form_schema';
|
||||
import {
|
||||
MatchedItem,
|
||||
RollupIndicesCapsResponse,
|
||||
IndexPatternConfig,
|
||||
MatchedIndicesSet,
|
||||
} from '../../types';
|
||||
import { RollupIndicesCapsResponse, IndexPatternConfig, MatchedIndicesSet } from '../../types';
|
||||
|
||||
interface RefreshMatchedIndicesResult {
|
||||
matchedIndicesResult: MatchedIndicesSet;
|
||||
|
|
|
@ -20,9 +20,10 @@ import {
|
|||
EuiBadge,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { INDEX_PATTERN_TYPE } from '@kbn/data-views-plugin/public';
|
||||
import { UseField } from '../../shared_imports';
|
||||
|
||||
import { INDEX_PATTERN_TYPE, IndexPatternConfig } from '../../types';
|
||||
import { IndexPatternConfig } from '../../types';
|
||||
|
||||
interface TypeFieldProps {
|
||||
onChange: (type: INDEX_PATTERN_TYPE) => void;
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { INDEX_PATTERN_TYPE } from '@kbn/data-views-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { fieldValidators, ValidationFunc } from '../shared_imports';
|
||||
import { INDEX_PATTERN_TYPE } from '../types';
|
||||
|
||||
export const singleAstriskValidator = (
|
||||
...args: Parameters<ValidationFunc>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import React from 'react';
|
||||
import { IndicesList } from '.';
|
||||
import { shallow } from 'enzyme';
|
||||
import { MatchedItem } from '../../../types';
|
||||
import { MatchedItem } from '@kbn/data-views-plugin/public';
|
||||
|
||||
const indices = [
|
||||
{ name: 'kibana', tags: [] },
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
import { Pager } from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { MatchedItem, Tag } from '../../../types';
|
||||
import { MatchedItem, Tag } from '@kbn/data-views-plugin/public';
|
||||
|
||||
interface IndicesListProps {
|
||||
indices: MatchedItem[];
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { INDEX_PATTERN_TYPE } from '@kbn/data-views-plugin/public';
|
||||
import { StatusMessage } from './status_message';
|
||||
import { IndicesList } from './indices_list';
|
||||
|
||||
import { INDEX_PATTERN_TYPE, MatchedIndicesSet } from '../../types';
|
||||
import { MatchedIndicesSet } from '../../types';
|
||||
|
||||
interface Props {
|
||||
type: INDEX_PATTERN_TYPE;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import React from 'react';
|
||||
import { StatusMessage } from '.';
|
||||
import { shallow } from 'enzyme';
|
||||
import { MatchedItem } from '../../../types';
|
||||
import { MatchedItem } from '@kbn/data-views-plugin/public';
|
||||
|
||||
const tagsPartial = {
|
||||
tags: [],
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { MatchedItem } from '@kbn/data-views-plugin/public';
|
||||
import { Tag } from '@kbn/data-views-plugin/public/types';
|
||||
import { getMatchedIndices } from './get_matched_indices';
|
||||
import { Tag, MatchedItem } from '../types';
|
||||
|
||||
jest.mock('../constants', () => ({
|
||||
MAX_NUMBER_OF_MATCHING_INDICES: 6,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { MatchedItem } from '@kbn/data-views-plugin/public';
|
||||
import { MAX_NUMBER_OF_MATCHING_INDICES } from '../constants';
|
||||
|
||||
function isSystemIndex(index: string): boolean {
|
||||
|
@ -50,7 +51,7 @@ function filterSystemIndices(indices: MatchedItem[], isIncludingSystemIndices: b
|
|||
We call this `exact` matches because ES is telling us exactly what it matches
|
||||
*/
|
||||
|
||||
import { MatchedItem, MatchedIndicesSet } from '../types';
|
||||
import { MatchedIndicesSet } from '../types';
|
||||
|
||||
export function getMatchedIndices(
|
||||
unfilteredAllIndices: MatchedItem[],
|
||||
|
|
|
@ -10,8 +10,6 @@ export { canAppendWildcard } from './can_append_wildcard';
|
|||
|
||||
export { ensureMinimumTime } from './ensure_minimum_time';
|
||||
|
||||
export { getIndices } from './get_indices';
|
||||
|
||||
export { getMatchedIndices } from './get_matched_indices';
|
||||
|
||||
export { containsIllegalCharacters } from './contains_illegal_characters';
|
||||
|
|
|
@ -17,7 +17,12 @@ import {
|
|||
|
||||
import { EuiComboBoxOptionOption } from '@elastic/eui';
|
||||
|
||||
import type { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||
import type {
|
||||
DataView,
|
||||
DataViewsPublicPluginStart,
|
||||
INDEX_PATTERN_TYPE,
|
||||
MatchedItem,
|
||||
} from '@kbn/data-views-plugin/public';
|
||||
import { DataPublicPluginStart, IndexPatternAggRestrictions } from './shared_imports';
|
||||
|
||||
export interface DataViewEditorContext {
|
||||
|
@ -80,51 +85,6 @@ export interface StartPlugins {
|
|||
|
||||
export type CloseEditor = () => void;
|
||||
|
||||
export interface MatchedItem {
|
||||
name: string;
|
||||
tags: Tag[];
|
||||
item: {
|
||||
name: string;
|
||||
backing_indices?: string[];
|
||||
timestamp_field?: string;
|
||||
indices?: string[];
|
||||
aliases?: string[];
|
||||
attributes?: ResolveIndexResponseItemIndexAttrs[];
|
||||
data_stream?: string;
|
||||
};
|
||||
}
|
||||
|
||||
// for showing index matches
|
||||
export interface ResolveIndexResponse {
|
||||
indices?: ResolveIndexResponseItemIndex[];
|
||||
aliases?: ResolveIndexResponseItemAlias[];
|
||||
data_streams?: ResolveIndexResponseItemDataStream[];
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItem {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemDataStream extends ResolveIndexResponseItem {
|
||||
backing_indices: string[];
|
||||
timestamp_field: string;
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemAlias extends ResolveIndexResponseItem {
|
||||
indices: string[];
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemIndex extends ResolveIndexResponseItem {
|
||||
aliases?: string[];
|
||||
attributes?: ResolveIndexResponseItemIndexAttrs[];
|
||||
data_stream?: string;
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
name: string;
|
||||
key: string;
|
||||
color: string;
|
||||
}
|
||||
// end for index matches
|
||||
|
||||
export interface IndexPatternTableItem {
|
||||
|
@ -135,13 +95,6 @@ export interface IndexPatternTableItem {
|
|||
sort: string;
|
||||
}
|
||||
|
||||
export enum ResolveIndexResponseItemIndexAttrs {
|
||||
OPEN = 'open',
|
||||
CLOSED = 'closed',
|
||||
HIDDEN = 'hidden',
|
||||
FROZEN = 'frozen',
|
||||
}
|
||||
|
||||
export interface RollupIndiciesCapability {
|
||||
aggs: Record<string, IndexPatternAggRestrictions>;
|
||||
error: string;
|
||||
|
@ -149,11 +102,6 @@ export interface RollupIndiciesCapability {
|
|||
|
||||
export type RollupIndicesCapsResponse = Record<string, RollupIndiciesCapability>;
|
||||
|
||||
export enum INDEX_PATTERN_TYPE {
|
||||
ROLLUP = 'rollup',
|
||||
DEFAULT = 'default',
|
||||
}
|
||||
|
||||
export interface IndexPatternConfig {
|
||||
title: string;
|
||||
timestampField?: EuiComboBoxOptionOption<string>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { DataViewsService } from '.';
|
||||
import { DataViewsService, MatchedItem } from '.';
|
||||
|
||||
import { DataViewsServiceDeps } from '../common/data_views/data_views';
|
||||
import { HasDataService } from '../common';
|
||||
|
@ -24,6 +24,11 @@ export interface DataViewsServicePublicDeps extends DataViewsServiceDeps {
|
|||
* Has data service
|
||||
*/
|
||||
hasData: HasDataService;
|
||||
getIndices: (props: {
|
||||
pattern: string;
|
||||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +37,12 @@ export interface DataViewsServicePublicDeps extends DataViewsServiceDeps {
|
|||
*/
|
||||
export class DataViewsServicePublic extends DataViewsService {
|
||||
public getCanSaveSync: () => boolean;
|
||||
|
||||
public getIndices: (props: {
|
||||
pattern: string;
|
||||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
public hasData: HasDataService;
|
||||
|
||||
/**
|
||||
|
@ -43,5 +54,6 @@ export class DataViewsServicePublic extends DataViewsService {
|
|||
super(deps);
|
||||
this.getCanSaveSync = deps.getCanSaveSync;
|
||||
this.hasData = deps.hasData;
|
||||
this.getIndices = deps.getIndices;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,14 @@ export {
|
|||
getFieldSubtypeNested,
|
||||
} from '../common';
|
||||
|
||||
export type { DataViewsPublicSetupDependencies, DataViewsPublicStartDependencies } from './types';
|
||||
export type {
|
||||
DataViewsPublicSetupDependencies,
|
||||
DataViewsPublicStartDependencies,
|
||||
MatchedItem,
|
||||
Tag,
|
||||
} from './types';
|
||||
|
||||
export { INDEX_PATTERN_TYPE } from './types';
|
||||
|
||||
export type {
|
||||
DataViewsServicePublic,
|
||||
|
|
|
@ -21,7 +21,7 @@ import { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper
|
|||
import { UiSettingsPublicToCommon } from './ui_settings_wrapper';
|
||||
|
||||
import { DataViewsServicePublic } from './data_views_service_public';
|
||||
import { HasData } from './services';
|
||||
import { getIndices, HasData } from './services';
|
||||
|
||||
import { debounceByKey } from './debounce_by_key';
|
||||
|
||||
|
@ -76,6 +76,7 @@ export class DataViewsPublicPlugin
|
|||
getCanSaveSync: () => application.capabilities.indexPatterns.save === true,
|
||||
getCanSaveAdvancedSettings: () =>
|
||||
Promise.resolve(application.capabilities.advancedSettings.save === true),
|
||||
getIndices: (props) => getIndices({ ...props, http: core.http }),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,20 +12,20 @@ import { i18n } from '@kbn/i18n';
|
|||
import { Tag, INDEX_PATTERN_TYPE } from '../types';
|
||||
import { MatchedItem, ResolveIndexResponse, ResolveIndexResponseItemIndexAttrs } from '../types';
|
||||
|
||||
const aliasLabel = i18n.translate('indexPatternEditor.aliasLabel', { defaultMessage: 'Alias' });
|
||||
const dataStreamLabel = i18n.translate('indexPatternEditor.dataStreamLabel', {
|
||||
const aliasLabel = i18n.translate('dataViews.aliasLabel', { defaultMessage: 'Alias' });
|
||||
const dataStreamLabel = i18n.translate('dataViews.dataStreamLabel', {
|
||||
defaultMessage: 'Data stream',
|
||||
});
|
||||
|
||||
const indexLabel = i18n.translate('indexPatternEditor.indexLabel', {
|
||||
const indexLabel = i18n.translate('dataViews.indexLabel', {
|
||||
defaultMessage: 'Index',
|
||||
});
|
||||
|
||||
const frozenLabel = i18n.translate('indexPatternEditor.frozenLabel', {
|
||||
const frozenLabel = i18n.translate('dataViews.frozenLabel', {
|
||||
defaultMessage: 'Frozen',
|
||||
});
|
||||
|
||||
const rollupLabel = i18n.translate('indexPatternEditor.rollupLabel', {
|
||||
const rollupLabel = i18n.translate('dataViews.rollupLabel', {
|
||||
defaultMessage: 'Rollup',
|
||||
});
|
||||
|
|
@ -6,4 +6,17 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import { MatchedItem } from '../types';
|
||||
|
||||
export * from './has_data';
|
||||
|
||||
export async function getIndices(props: {
|
||||
http: HttpStart;
|
||||
pattern: string;
|
||||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}): Promise<MatchedItem[]> {
|
||||
const { getIndices: getIndicesLazy } = await import('./get_indices');
|
||||
return getIndicesLazy(props);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@ import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/
|
|||
import { DataViewsServicePublicMethods } from './data_views';
|
||||
import { HasDataService } from '../common';
|
||||
|
||||
export enum INDEX_PATTERN_TYPE {
|
||||
ROLLUP = 'rollup',
|
||||
DEFAULT = 'default',
|
||||
}
|
||||
|
||||
export enum IndicesResponseItemIndexAttrs {
|
||||
OPEN = 'open',
|
||||
CLOSED = 'closed',
|
||||
|
@ -98,6 +103,11 @@ export interface DataViewsPublicPluginSetup {}
|
|||
export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
|
||||
getCanSaveSync: () => boolean;
|
||||
hasData: HasDataService;
|
||||
getIndices: (props: {
|
||||
pattern: string;
|
||||
showAllIndices?: boolean;
|
||||
isRollupIndex: (indexName: string) => boolean;
|
||||
}) => Promise<MatchedItem[]>;
|
||||
}
|
||||
|
||||
export type DataViewsContract = DataViewsServicePublic;
|
||||
|
@ -106,3 +116,55 @@ export type DataViewsContract = DataViewsServicePublic;
|
|||
* Data views plugin public Start contract
|
||||
*/
|
||||
export type DataViewsPublicPluginStart = DataViewsServicePublic;
|
||||
|
||||
export interface MatchedItem {
|
||||
name: string;
|
||||
tags: Tag[];
|
||||
item: {
|
||||
name: string;
|
||||
backing_indices?: string[];
|
||||
timestamp_field?: string;
|
||||
indices?: string[];
|
||||
aliases?: string[];
|
||||
attributes?: ResolveIndexResponseItemIndexAttrs[];
|
||||
data_stream?: string;
|
||||
};
|
||||
}
|
||||
|
||||
// for showing index matches
|
||||
export interface ResolveIndexResponse {
|
||||
indices?: ResolveIndexResponseItemIndex[];
|
||||
aliases?: ResolveIndexResponseItemAlias[];
|
||||
data_streams?: ResolveIndexResponseItemDataStream[];
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItem {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemDataStream extends ResolveIndexResponseItem {
|
||||
backing_indices: string[];
|
||||
timestamp_field: string;
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemAlias extends ResolveIndexResponseItem {
|
||||
indices: string[];
|
||||
}
|
||||
|
||||
export interface ResolveIndexResponseItemIndex extends ResolveIndexResponseItem {
|
||||
aliases?: string[];
|
||||
attributes?: ResolveIndexResponseItemIndexAttrs[];
|
||||
data_stream?: string;
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
name: string;
|
||||
key: string;
|
||||
color: string;
|
||||
}
|
||||
export enum ResolveIndexResponseItemIndexAttrs {
|
||||
OPEN = 'open',
|
||||
CLOSED = 'closed',
|
||||
HIDDEN = 'hidden',
|
||||
FROZEN = 'frozen',
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ export const DiscoverTopNav = ({
|
|||
[dataView]
|
||||
);
|
||||
const services = useDiscoverServices();
|
||||
const { dataViewEditor, navigation, dataViewFieldEditor, data, uiSettings } = services;
|
||||
const { dataViewEditor, navigation, dataViewFieldEditor, data, uiSettings, dataViews } = services;
|
||||
|
||||
const canEditDataView = Boolean(dataViewEditor?.userPermissions.editDataView());
|
||||
|
||||
|
@ -141,6 +141,19 @@ export const DiscoverTopNav = ({
|
|||
[canEditDataView, dataViewEditor, onChangeDataView]
|
||||
);
|
||||
|
||||
const onCreateDefaultAdHocDataView = useCallback(
|
||||
async (pattern: string) => {
|
||||
const newDataView = await dataViews.create({
|
||||
title: pattern,
|
||||
});
|
||||
if (newDataView.fields.getByName('@timestamp')?.type === 'date') {
|
||||
newDataView.timeFieldName = '@timestamp';
|
||||
}
|
||||
onChangeDataView(newDataView.id!);
|
||||
},
|
||||
[dataViews, onChangeDataView]
|
||||
);
|
||||
|
||||
const topNavMenu = useMemo(
|
||||
() =>
|
||||
getTopNavLinks({
|
||||
|
@ -201,6 +214,7 @@ export const DiscoverTopNav = ({
|
|||
currentDataViewId: dataView?.id,
|
||||
onAddField: addField,
|
||||
onDataViewCreated: createNewDataView,
|
||||
onCreateDefaultAdHocDataView,
|
||||
onChangeDataView,
|
||||
textBasedLanguages: supportedTextBasedLanguages as DataViewPickerProps['textBasedLanguages'],
|
||||
adHocDataViews: adHocDataViewList,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import {
|
||||
EuiPopover,
|
||||
|
@ -24,6 +24,7 @@ import {
|
|||
EuiFlexItem,
|
||||
EuiButtonEmpty,
|
||||
EuiToolTip,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import type { DataViewListItem } from '@kbn/data-views-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
@ -71,9 +72,13 @@ export function ChangeDataView({
|
|||
onTextLangQuerySubmit,
|
||||
textBasedLanguage,
|
||||
isDisabled,
|
||||
onCreateDefaultAdHocDataView,
|
||||
}: DataViewPickerPropsExtended) {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const [isPopoverOpen, setPopoverIsOpen] = useState(false);
|
||||
const [noDataViewMatches, setNoDataViewMatches] = useState(false);
|
||||
const [dataViewSearchString, setDataViewSearchString] = useState('');
|
||||
const [indexMatches, setIndexMatches] = useState(0);
|
||||
const [dataViewsList, setDataViewsList] = useState<DataViewListItem[]>([]);
|
||||
const [triggerLabel, setTriggerLabel] = useState('');
|
||||
const [isTextBasedLangSelected, setIsTextBasedLangSelected] = useState(
|
||||
|
@ -111,6 +116,24 @@ export function ChangeDataView({
|
|||
fetchDataViews();
|
||||
}, [data, currentDataViewId, adHocDataViews]);
|
||||
|
||||
const pendingIndexMatch = useRef<undefined | NodeJS.Timeout>();
|
||||
useEffect(() => {
|
||||
async function checkIndices() {
|
||||
if (dataViewSearchString !== '' && noDataViewMatches) {
|
||||
const matches = await kibana.services.dataViews.getIndices({
|
||||
pattern: dataViewSearchString,
|
||||
isRollupIndex: () => false,
|
||||
showAllIndices: false,
|
||||
});
|
||||
setIndexMatches(matches.length);
|
||||
}
|
||||
}
|
||||
if (pendingIndexMatch.current) {
|
||||
clearTimeout(pendingIndexMatch.current);
|
||||
}
|
||||
pendingIndexMatch.current = setTimeout(checkIndices, 250);
|
||||
}, [dataViewSearchString, kibana.services.dataViews, noDataViewMatches]);
|
||||
|
||||
useEffect(() => {
|
||||
if (trigger.label) {
|
||||
if (textBasedLanguage) {
|
||||
|
@ -282,10 +305,57 @@ export function ChangeDataView({
|
|||
}
|
||||
}}
|
||||
currentDataViewId={currentDataViewId}
|
||||
selectableProps={selectableProps}
|
||||
selectableProps={{
|
||||
...(selectableProps || {}),
|
||||
// @ts-expect-error Some EUI weirdness
|
||||
searchProps: {
|
||||
...(selectableProps?.searchProps || {}),
|
||||
onChange: (value, matches) => {
|
||||
selectableProps?.searchProps?.onChange?.(value, matches);
|
||||
setNoDataViewMatches(matches.length === 0 && dataViewsList.length > 0);
|
||||
setDataViewSearchString(value);
|
||||
},
|
||||
},
|
||||
}}
|
||||
searchListInputId={searchListInputId}
|
||||
isTextBasedLangSelected={isTextBasedLangSelected}
|
||||
/>
|
||||
{onCreateDefaultAdHocDataView && noDataViewMatches && indexMatches > 0 && (
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
data-test-subj="select-text-based-language-panel"
|
||||
css={css`
|
||||
margin: ${euiTheme.size.s};
|
||||
margin-bottom: 0;
|
||||
`}
|
||||
>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiButton
|
||||
fullWidth
|
||||
size="s"
|
||||
onClick={() => {
|
||||
setPopoverIsOpen(false);
|
||||
onCreateDefaultAdHocDataView(dataViewSearchString);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'unifiedSearch.query.queryBar.indexPattern.createForMatchingIndices',
|
||||
{
|
||||
defaultMessage: `Explore {indicesLength, plural,
|
||||
one {# matching index}
|
||||
other {# matching indices}}`,
|
||||
values: {
|
||||
indicesLength: indexMatches,
|
||||
},
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
<EuiSpacer size="s" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ export interface DataViewPickerProps {
|
|||
* Also works as a flag to show the create dataview button.
|
||||
*/
|
||||
onDataViewCreated?: () => void;
|
||||
|
||||
onCreateDefaultAdHocDataView?: (pattern: string) => void;
|
||||
/**
|
||||
* List of the supported text based languages (SQL, ESQL) etc.
|
||||
* Defined per application, if not provided, no text based languages
|
||||
|
@ -104,6 +106,7 @@ export const DataViewPicker = ({
|
|||
onSaveTextLanguageQuery,
|
||||
onTextLangQuerySubmit,
|
||||
textBasedLanguage,
|
||||
onCreateDefaultAdHocDataView,
|
||||
isDisabled,
|
||||
}: DataViewPickerPropsExtended) => {
|
||||
return (
|
||||
|
@ -113,6 +116,7 @@ export const DataViewPicker = ({
|
|||
onChangeDataView={onChangeDataView}
|
||||
onAddField={onAddField}
|
||||
onDataViewCreated={onDataViewCreated}
|
||||
onCreateDefaultAdHocDataView={onCreateDefaultAdHocDataView}
|
||||
trigger={trigger}
|
||||
adHocDataViews={adHocDataViews}
|
||||
selectableProps={selectableProps}
|
||||
|
|
|
@ -86,5 +86,6 @@ export interface IUnifiedSearchPluginServices extends Partial<CoreStart> {
|
|||
storage: IStorageWrapper;
|
||||
docLinks: DocLinksStart;
|
||||
data: DataPublicPluginStart;
|
||||
dataViews: DataViewsPublicPluginStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
{ "path": "../../core/tsconfig.json" },
|
||||
{ "path": "../data/tsconfig.json" },
|
||||
{ "path": "../data_views/tsconfig.json" },
|
||||
{ "path": "../data_view_editor/tsconfig.json" },
|
||||
{ "path": "../embeddable/tsconfig.json" },
|
||||
{ "path": "../usage_collection/tsconfig.json" },
|
||||
{ "path": "../kibana_utils/tsconfig.json" },
|
||||
|
|
|
@ -15,8 +15,8 @@ import { downloadMultipleAs } from '@kbn/share-plugin/public';
|
|||
import { tableHasFormulas } from '@kbn/data-plugin/common';
|
||||
import { exporters, getEsQueryConfig } from '@kbn/data-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { DataViewPickerProps } from '@kbn/unified-search-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { DataViewPickerProps } from '@kbn/unified-search-plugin/public';
|
||||
import { ENABLE_SQL } from '../../common';
|
||||
import {
|
||||
LensAppServices,
|
||||
|
@ -768,13 +768,15 @@ export const LensTopNavMenu = ({
|
|||
closeDataViewEditor.current = dataViewEditor.openEditor({
|
||||
onSave: async (dataView) => {
|
||||
if (dataView.id) {
|
||||
dispatch(
|
||||
switchAndCleanDatasource({
|
||||
newDatasourceId: 'indexpattern',
|
||||
visualizationId: visualization?.activeId,
|
||||
currentIndexPatternId: dataView?.id,
|
||||
})
|
||||
);
|
||||
if (isOnTextBasedMode) {
|
||||
dispatch(
|
||||
switchAndCleanDatasource({
|
||||
newDatasourceId: 'indexpattern',
|
||||
visualizationId: visualization?.activeId,
|
||||
currentIndexPatternId: dataView?.id,
|
||||
})
|
||||
);
|
||||
}
|
||||
dispatchChangeIndexPattern(dataView);
|
||||
setCurrentIndexPattern(dataView);
|
||||
}
|
||||
|
@ -783,7 +785,43 @@ export const LensTopNavMenu = ({
|
|||
});
|
||||
}
|
||||
: undefined,
|
||||
[canEditDataView, dataViewEditor, dispatch, dispatchChangeIndexPattern, visualization?.activeId]
|
||||
[
|
||||
canEditDataView,
|
||||
dataViewEditor,
|
||||
dispatch,
|
||||
dispatchChangeIndexPattern,
|
||||
isOnTextBasedMode,
|
||||
visualization?.activeId,
|
||||
]
|
||||
);
|
||||
|
||||
const onCreateDefaultAdHocDataView = useCallback(
|
||||
async (pattern: string) => {
|
||||
const dataView = await dataViewsService.create({
|
||||
title: pattern,
|
||||
});
|
||||
if (dataView.fields.getByName('@timestamp')?.type === 'date') {
|
||||
dataView.timeFieldName = '@timestamp';
|
||||
}
|
||||
if (isOnTextBasedMode) {
|
||||
dispatch(
|
||||
switchAndCleanDatasource({
|
||||
newDatasourceId: 'indexpattern',
|
||||
visualizationId: visualization?.activeId,
|
||||
currentIndexPatternId: dataView?.id,
|
||||
})
|
||||
);
|
||||
}
|
||||
dispatchChangeIndexPattern(dataView);
|
||||
setCurrentIndexPattern(dataView);
|
||||
},
|
||||
[
|
||||
dataViewsService,
|
||||
dispatch,
|
||||
dispatchChangeIndexPattern,
|
||||
isOnTextBasedMode,
|
||||
visualization?.activeId,
|
||||
]
|
||||
);
|
||||
|
||||
// setting that enables/disables SQL
|
||||
|
@ -793,7 +831,7 @@ export const LensTopNavMenu = ({
|
|||
supportedTextBasedLanguages.push('SQL');
|
||||
}
|
||||
|
||||
const dataViewPickerProps = {
|
||||
const dataViewPickerProps: DataViewPickerProps = {
|
||||
trigger: {
|
||||
label: currentIndexPattern?.getName?.() || '',
|
||||
'data-test-subj': 'lns-dataView-switch-link',
|
||||
|
@ -802,6 +840,7 @@ export const LensTopNavMenu = ({
|
|||
currentDataViewId: currentIndexPattern?.id,
|
||||
onAddField: addField,
|
||||
onDataViewCreated: createNewDataView,
|
||||
onCreateDefaultAdHocDataView,
|
||||
adHocDataViews: indexPatterns.filter((pattern) => !pattern.isPersisted()),
|
||||
onChangeDataView: (newIndexPatternId: string) => {
|
||||
const currentDataView = dataViewsList.find(
|
||||
|
|
|
@ -3720,10 +3720,10 @@
|
|||
"indexPatternEditor.status.partialMatchLabel.partialMatchDetail": "Votre modèle d'indexation ne correspond à aucun flux de données, index ni alias d'index, mais {strongIndices} {matchedIndicesLength, plural, one {est semblable} other {sont semblables} }.",
|
||||
"indexPatternEditor.status.partialMatchLabel.strongIndicesLabel": "{matchedIndicesLength, plural, one {source} other {# sources} }",
|
||||
"indexPatternEditor.status.successLabel.successDetail": "Votre modèle d'indexation correspond à {sourceCount} {sourceCount, plural, one {source} other {sources} }.",
|
||||
"indexPatternEditor.aliasLabel": "Alias",
|
||||
"dataViews.aliasLabel": "Alias",
|
||||
"indexPatternEditor.createIndex.noMatch": "Le nom doit correspondre à au moins un flux de données, index ou alias d'index.",
|
||||
"indexPatternEditor.createIndexPattern.stepTime.noTimeFieldOptionLabel": "--- Je ne souhaite pas utiliser le filtre temporel ---",
|
||||
"indexPatternEditor.dataStreamLabel": "Flux de données",
|
||||
"dataViews.dataStreamLabel": "Flux de données",
|
||||
"indexPatternEditor.dataView.unableSaveLabel": "Échec de l'enregistrement de la vue de données.",
|
||||
"indexPatternEditor.dataViewExists.ValidationErrorMessage": "Une vue de données de ce nom existe déjà.",
|
||||
"indexPatternEditor.editDataView.editConfirmationModal.confirmButton": "Confirmer",
|
||||
|
@ -3754,8 +3754,8 @@
|
|||
"indexPatternEditor.form.customIndexPatternIdLabel": "ID de vue de données personnalisé",
|
||||
"indexPatternEditor.form.nameAriaLabel": "Champ de nom facultatif",
|
||||
"indexPatternEditor.form.titleAriaLabel": "Champ de modèle d'indexation",
|
||||
"indexPatternEditor.frozenLabel": "Frozen",
|
||||
"indexPatternEditor.indexLabel": "Index",
|
||||
"dataViews.frozenLabel": "Frozen",
|
||||
"dataViews.indexLabel": "Index",
|
||||
"indexPatternEditor.loadingHeader": "Recherche d'index correspondants…",
|
||||
"indexPatternEditor.requireTimestampOption.ValidationErrorMessage": "Sélectionnez un champ d'horodatage.",
|
||||
"indexPatternEditor.rollupDataView.createIndex.noMatchError": "Erreur de vue de données de cumul : doit correspondre à un index de cumul",
|
||||
|
@ -3763,7 +3763,7 @@
|
|||
"indexPatternEditor.rollupDataView.warning.textParagraphOne": "Kibana propose un support bêta pour les vues de données basées sur les cumuls. Vous pourriez rencontrer des problèmes lors de l'utilisation de ces vues dans les recherches enregistrées, les visualisations et les tableaux de bord. Ils ne sont pas compatibles avec certaines fonctionnalités avancées, telles que Timelion et le Machine Learning.",
|
||||
"indexPatternEditor.rollupDataView.warning.textParagraphTwo": "Vous pouvez mettre une vue de données de cumul en correspondance avec un index de cumul et zéro index régulier ou plus. Une vue de données de cumul dispose d'indicateurs, de champs, d'intervalles et d'agrégations limités. Un index de cumul se limite aux index disposant d'une configuration de tâche ou de plusieurs tâches avec des configurations compatibles.",
|
||||
"indexPatternEditor.rollupIndexPattern.warning.title": "Fonctionnalité bêta",
|
||||
"indexPatternEditor.rollupLabel": "Cumul",
|
||||
"dataViews.rollupLabel": "Cumul",
|
||||
"indexPatternEditor.saved": "'{indexPatternName}' enregistré",
|
||||
"indexPatternEditor.status.noSystemIndicesLabel": "Aucun flux de données, index ni alias d'index ne correspond à votre modèle d'indexation.",
|
||||
"indexPatternEditor.status.noSystemIndicesWithPromptLabel": "Aucun flux de données, index ni alias d'index ne correspond à votre modèle d'indexation.",
|
||||
|
|
|
@ -3715,10 +3715,10 @@
|
|||
"indexPatternEditor.status.partialMatchLabel.partialMatchDetail": "インデックスパターンはどのデータストリーム、インデックス、インデックスエイリアスとも一致しませんが、{strongIndices} {matchedIndicesLength, plural, other {が} }類似しています。",
|
||||
"indexPatternEditor.status.partialMatchLabel.strongIndicesLabel": "{matchedIndicesLength, plural, other {# ソース} }",
|
||||
"indexPatternEditor.status.successLabel.successDetail": "インデックスパターンは、{sourceCount} {sourceCount, plural, other {ソース} }と一致します。",
|
||||
"indexPatternEditor.aliasLabel": "エイリアス",
|
||||
"dataViews.aliasLabel": "エイリアス",
|
||||
"indexPatternEditor.createIndex.noMatch": "名前は1つ以上のデータストリーム、インデックス、またはインデックスエイリアスと一致する必要があります。",
|
||||
"indexPatternEditor.createIndexPattern.stepTime.noTimeFieldOptionLabel": "--- 時間フィルターを使用しない ---",
|
||||
"indexPatternEditor.dataStreamLabel": "データストリーム",
|
||||
"dataViews.dataStreamLabel": "データストリーム",
|
||||
"indexPatternEditor.dataView.unableSaveLabel": "データビューの保存に失敗しました。",
|
||||
"indexPatternEditor.dataViewExists.ValidationErrorMessage": "この名前のデータビューはすでに存在します。",
|
||||
"indexPatternEditor.editDataView.editConfirmationModal.confirmButton": "確認",
|
||||
|
@ -3749,8 +3749,8 @@
|
|||
"indexPatternEditor.form.customIndexPatternIdLabel": "カスタムデータビューID",
|
||||
"indexPatternEditor.form.nameAriaLabel": "名前フィールド(任意)",
|
||||
"indexPatternEditor.form.titleAriaLabel": "インデックスパターンフィールド",
|
||||
"indexPatternEditor.frozenLabel": "凍結",
|
||||
"indexPatternEditor.indexLabel": "インデックス",
|
||||
"dataViews.frozenLabel": "凍結",
|
||||
"dataViews.indexLabel": "インデックス",
|
||||
"indexPatternEditor.loadingHeader": "一致するインデックスを検索中…",
|
||||
"indexPatternEditor.requireTimestampOption.ValidationErrorMessage": "タイムスタンプフィールドを選択します。",
|
||||
"indexPatternEditor.rollupDataView.createIndex.noMatchError": "ロールアップデータビューエラー:ロールアップインデックスの 1 つと一致している必要があります",
|
||||
|
@ -3758,7 +3758,7 @@
|
|||
"indexPatternEditor.rollupDataView.warning.textParagraphOne": "Kibanaではロールアップに基づいてデータビューのデータサポートを提供します。保存された検索、可視化、ダッシュボードでこれらを使用すると問題が発生する場合があります。Timelionや機械学習などの一部の高度な機能ではサポートされていません。",
|
||||
"indexPatternEditor.rollupDataView.warning.textParagraphTwo": "ロールアップデータビューは、1つのロールアップインデックスとゼロ以上の標準インデックスと一致させることができます。ロールアップデータビューでは、メトリック、フィールド、間隔、アグリゲーションが制限されています。ロールアップインデックスは、1つのジョブ構成があるインデックス、または複数のジョブと互換する構成があるインデックスに制限されています。",
|
||||
"indexPatternEditor.rollupIndexPattern.warning.title": "ベータ機能",
|
||||
"indexPatternEditor.rollupLabel": "ロールアップ",
|
||||
"dataViews.rollupLabel": "ロールアップ",
|
||||
"indexPatternEditor.saved": "'{indexPatternName}'が保存されました",
|
||||
"indexPatternEditor.status.noSystemIndicesLabel": "データストリーム、インデックス、またはインデックスエイリアスがインデックスパターンと一致しません。",
|
||||
"indexPatternEditor.status.noSystemIndicesWithPromptLabel": "データストリーム、インデックス、またはインデックスエイリアスがインデックスパターンと一致しません。",
|
||||
|
|
|
@ -3720,10 +3720,10 @@
|
|||
"indexPatternEditor.status.partialMatchLabel.partialMatchDetail": "您的索引模式不匹配任何数据流、索引或索引别名,但{strongIndices}{matchedIndicesLength, plural, other {} }类似。",
|
||||
"indexPatternEditor.status.partialMatchLabel.strongIndicesLabel": "{matchedIndicesLength, plural, one {个源} other {# 个源} }",
|
||||
"indexPatternEditor.status.successLabel.successDetail": "您的索引模式匹配 {sourceCount} 个{sourceCount, plural, other {源} }。",
|
||||
"indexPatternEditor.aliasLabel": "别名",
|
||||
"dataViews.aliasLabel": "别名",
|
||||
"indexPatternEditor.createIndex.noMatch": "名称必须匹配一个或多个数据流、索引或索引别名。",
|
||||
"indexPatternEditor.createIndexPattern.stepTime.noTimeFieldOptionLabel": "--- 我不想使用时间筛选 ---",
|
||||
"indexPatternEditor.dataStreamLabel": "数据流",
|
||||
"dataViews.dataStreamLabel": "数据流",
|
||||
"indexPatternEditor.dataView.unableSaveLabel": "无法保存数据视图。",
|
||||
"indexPatternEditor.dataViewExists.ValidationErrorMessage": "具有此名称的数据视图已存在。",
|
||||
"indexPatternEditor.editDataView.editConfirmationModal.confirmButton": "确认",
|
||||
|
@ -3754,8 +3754,8 @@
|
|||
"indexPatternEditor.form.customIndexPatternIdLabel": "定制数据视图 ID",
|
||||
"indexPatternEditor.form.nameAriaLabel": "名称字段(可选)",
|
||||
"indexPatternEditor.form.titleAriaLabel": "索引模式字段",
|
||||
"indexPatternEditor.frozenLabel": "已冻结",
|
||||
"indexPatternEditor.indexLabel": "索引",
|
||||
"dataViews.frozenLabel": "已冻结",
|
||||
"dataViews.indexLabel": "索引",
|
||||
"indexPatternEditor.loadingHeader": "正在寻找匹配的索引......",
|
||||
"indexPatternEditor.requireTimestampOption.ValidationErrorMessage": "选择时间戳字段。",
|
||||
"indexPatternEditor.rollupDataView.createIndex.noMatchError": "汇总/打包数据视图错误:必须匹配一个汇总/打包索引",
|
||||
|
@ -3763,7 +3763,7 @@
|
|||
"indexPatternEditor.rollupDataView.warning.textParagraphOne": "Kibana 基于汇总/打包为数据视图提供公测版支持。将这些视图用于已保存搜索、可视化以及仪表板可能会遇到问题。某些高级功能,如 Timelion 和 Machine Learning,不支持这些模式。",
|
||||
"indexPatternEditor.rollupDataView.warning.textParagraphTwo": "可以根据一个汇总/打包索引和零个或更多常规索引匹配汇总/打包数据视图。汇总/打包数据视图的指标、字段、时间间隔和聚合有限。汇总/打包索引仅限于具有一个作业配置或多个作业配置兼容的索引。",
|
||||
"indexPatternEditor.rollupIndexPattern.warning.title": "公测版功能",
|
||||
"indexPatternEditor.rollupLabel": "汇总/打包",
|
||||
"dataViews.rollupLabel": "汇总/打包",
|
||||
"indexPatternEditor.saved": "已保存“{indexPatternName}”",
|
||||
"indexPatternEditor.status.noSystemIndicesLabel": "没有数据流、索引或索引别名匹配您的索引模式。",
|
||||
"indexPatternEditor.status.noSystemIndicesWithPromptLabel": "没有数据流、索引或索引别名匹配您的索引模式。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue