mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Update example plugins to stop using deprecated APIs (#121547)
This commit is contained in:
parent
f1bb5ea96c
commit
2fa5a87a5f
18 changed files with 199 additions and 208 deletions
|
@ -20,23 +20,20 @@ import {
|
|||
DefaultItemAction,
|
||||
} from '@elastic/eui';
|
||||
import { AppMountParameters } from '../../../src/core/public';
|
||||
import {
|
||||
DataPublicPluginStart,
|
||||
IndexPattern,
|
||||
IndexPatternField,
|
||||
} from '../../../src/plugins/data/public';
|
||||
import { DataPublicPluginStart } from '../../../src/plugins/data/public';
|
||||
import type { DataView, DataViewField } from '../../../src/plugins/data_views/public';
|
||||
import { IndexPatternFieldEditorStart } from '../../../src/plugins/data_view_field_editor/public';
|
||||
|
||||
interface Props {
|
||||
indexPattern?: IndexPattern;
|
||||
dataView?: DataView;
|
||||
dataViewFieldEditor: IndexPatternFieldEditorStart;
|
||||
}
|
||||
|
||||
const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: Props) => {
|
||||
const [fields, setFields] = useState<IndexPatternField[]>(
|
||||
indexPattern?.getNonScriptedFields() || []
|
||||
const DataViewFieldEditorExample = ({ dataView, dataViewFieldEditor }: Props) => {
|
||||
const [fields, setFields] = useState<DataViewField[]>(
|
||||
dataView?.fields.getAll().filter((f) => !f.scripted) || []
|
||||
);
|
||||
const refreshFields = () => setFields(indexPattern?.getNonScriptedFields() || []);
|
||||
const refreshFields = () => setFields(dataView?.fields.getAll().filter((f) => !f.scripted) || []);
|
||||
const columns = [
|
||||
{
|
||||
field: 'name',
|
||||
|
@ -51,9 +48,9 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P
|
|||
icon: 'pencil',
|
||||
type: 'icon',
|
||||
'data-test-subj': 'editField',
|
||||
onClick: (fld: IndexPatternField) =>
|
||||
onClick: (fld: DataViewField) =>
|
||||
dataViewFieldEditor.openEditor({
|
||||
ctx: { dataView: indexPattern! },
|
||||
ctx: { dataView: dataView! },
|
||||
fieldName: fld.name,
|
||||
onSave: refreshFields,
|
||||
}),
|
||||
|
@ -65,27 +62,27 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P
|
|||
type: 'icon',
|
||||
'data-test-subj': 'deleteField',
|
||||
available: (fld) => !!fld.runtimeField,
|
||||
onClick: (fld: IndexPatternField) =>
|
||||
onClick: (fld: DataViewField) =>
|
||||
dataViewFieldEditor.openDeleteModal({
|
||||
fieldName: fld.name,
|
||||
ctx: {
|
||||
dataView: indexPattern!,
|
||||
dataView: dataView!,
|
||||
},
|
||||
onDelete: refreshFields,
|
||||
}),
|
||||
},
|
||||
] as Array<DefaultItemAction<IndexPatternField>>,
|
||||
] as Array<DefaultItemAction<DataViewField>>,
|
||||
},
|
||||
];
|
||||
|
||||
const content = indexPattern ? (
|
||||
const content = dataView ? (
|
||||
<>
|
||||
<EuiText data-test-subj="indexPatternTitle">Index pattern: {indexPattern?.title}</EuiText>
|
||||
<EuiText data-test-subj="dataViewTitle">Data view: {dataView.title}</EuiText>
|
||||
<div>
|
||||
<EuiButton
|
||||
onClick={() =>
|
||||
dataViewFieldEditor.openEditor({
|
||||
ctx: { dataView: indexPattern! },
|
||||
ctx: { dataView },
|
||||
onSave: refreshFields,
|
||||
})
|
||||
}
|
||||
|
@ -94,7 +91,7 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P
|
|||
Add field
|
||||
</EuiButton>
|
||||
</div>
|
||||
<EuiInMemoryTable<IndexPatternField>
|
||||
<EuiInMemoryTable<DataViewField>
|
||||
items={fields}
|
||||
columns={columns}
|
||||
pagination={true}
|
||||
|
@ -108,13 +105,13 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P
|
|||
/>
|
||||
</>
|
||||
) : (
|
||||
<p>Please create an index pattern</p>
|
||||
<p>Please create a data view</p>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiPage>
|
||||
<EuiPageBody>
|
||||
<EuiPageHeader>Index pattern field editor demo</EuiPageHeader>
|
||||
<EuiPageHeader>Data view field editor demo</EuiPageHeader>
|
||||
<EuiPageContent>
|
||||
<EuiPageContentBody>{content}</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
|
@ -132,12 +129,9 @@ export const renderApp = async (
|
|||
{ data, dataViewFieldEditor }: RenderAppDependencies,
|
||||
{ element }: AppMountParameters
|
||||
) => {
|
||||
const indexPattern = (await data.indexPatterns.getDefault()) || undefined;
|
||||
const dataView = (await data.dataViews.getDefault()) || undefined;
|
||||
ReactDOM.render(
|
||||
<IndexPatternFieldEditorExample
|
||||
indexPattern={indexPattern}
|
||||
dataViewFieldEditor={dataViewFieldEditor}
|
||||
/>,
|
||||
<DataViewFieldEditorExample dataView={dataView} dataViewFieldEditor={dataViewFieldEditor} />,
|
||||
element
|
||||
);
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { IndexPatternFieldEditorPlugin } from './plugin';
|
||||
import { DataViewFieldEditorPlugin } from './plugin';
|
||||
|
||||
export const plugin = () => new IndexPatternFieldEditorPlugin();
|
||||
export const plugin = () => new DataViewFieldEditorPlugin();
|
||||
|
|
|
@ -20,11 +20,11 @@ interface SetupDeps {
|
|||
developerExamples: DeveloperExamplesSetup;
|
||||
}
|
||||
|
||||
export class IndexPatternFieldEditorPlugin implements Plugin<void, void, SetupDeps, StartDeps> {
|
||||
export class DataViewFieldEditorPlugin implements Plugin<void, void, SetupDeps, StartDeps> {
|
||||
public setup(core: CoreSetup<StartDeps>, deps: SetupDeps) {
|
||||
core.application.register({
|
||||
id: 'indexPatternFieldEditorExample',
|
||||
title: 'Index pattern field editor example',
|
||||
id: 'dataViewFieldEditorExample',
|
||||
title: 'Data view field editor example',
|
||||
navLinkStatus: AppNavLinkStatus.hidden,
|
||||
async mount(params: AppMountParameters) {
|
||||
const [, depsStart] = await core.getStartServices();
|
||||
|
@ -34,13 +34,13 @@ export class IndexPatternFieldEditorPlugin implements Plugin<void, void, SetupDe
|
|||
});
|
||||
|
||||
deps.developerExamples.register({
|
||||
appId: 'indexPatternFieldEditorExample',
|
||||
title: 'Index pattern field editor',
|
||||
description: `IndexPatternFieldEditor provides a UI for editing index pattern fields directly from Kibana apps. This example plugin demonstrates integration.`,
|
||||
appId: 'dataViewFieldEditorExample',
|
||||
title: 'Data view field editor',
|
||||
description: `DataViewFieldEditor provides a UI for editing data view fields directly from Kibana apps. This example plugin demonstrates integration.`,
|
||||
links: [
|
||||
{
|
||||
label: 'README',
|
||||
href: 'https://github.com/elastic/kibana/blob/main/src/plugins/index_pattern_field_editor/README.md',
|
||||
href: 'https://github.com/elastic/kibana/blob/main/src/plugins/data_view_field_editor/README.md',
|
||||
iconType: 'logoGithub',
|
||||
size: 's',
|
||||
target: '_blank',
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
{ "path": "../../src/core/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/kibana_react/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data_views/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data_view_field_editor/tsconfig.json" },
|
||||
{ "path": "../developer_examples/tsconfig.json" },
|
||||
]
|
||||
|
|
|
@ -43,7 +43,7 @@ export interface Deps {
|
|||
/**
|
||||
* Just for demo purposes
|
||||
*/
|
||||
openIndexPatternNumberFieldEditor: () => void;
|
||||
openDateViewNumberFieldEditor: () => void;
|
||||
}
|
||||
|
||||
const UsingAnExistingFieldFormatExample: React.FC<{ deps: Deps }> = (props) => {
|
||||
|
@ -123,15 +123,15 @@ const CreatingCustomFieldFormat: React.FC<{ deps: Deps }> = (props) => {
|
|||
<EuiSpacer size={'s'} />
|
||||
|
||||
<EuiCallOut
|
||||
title="Seamless integration with index patterns!"
|
||||
title="Seamless integration with data views!"
|
||||
color="success"
|
||||
iconType="indexManagementApp"
|
||||
>
|
||||
<p>
|
||||
Currency formatter that we've just created is already integrated with index patterns.
|
||||
It can be applied to any <EuiCode>numeric</EuiCode> field of any index pattern.{' '}
|
||||
<EuiLink onClick={() => props.deps.openIndexPatternNumberFieldEditor()}>
|
||||
Open index pattern field editor to give it a try.
|
||||
Currency formatter that we've just created is already integrated with data views. It
|
||||
can be applied to any <EuiCode>numeric</EuiCode> field of any data view.{' '}
|
||||
<EuiLink onClick={() => props.deps.openDateViewNumberFieldEditor()}>
|
||||
Open data view field editor to give it a try.
|
||||
</EuiLink>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
|
@ -155,15 +155,15 @@ const CreatingCustomFieldFormatEditor: React.FC<{ deps: Deps }> = (props) => {
|
|||
<EuiSpacer size={'s'} />
|
||||
|
||||
<EuiCallOut
|
||||
title="Check the result in the index pattern field editor!"
|
||||
title="Check the result in the data view field editor!"
|
||||
color="primary"
|
||||
iconType="indexManagementApp"
|
||||
>
|
||||
<p>
|
||||
Currency formatter and its custom editor are integrated with index patterns. It can be
|
||||
applied to any <EuiCode>numeric</EuiCode> field of any index pattern.{' '}
|
||||
<EuiLink onClick={() => props.deps.openIndexPatternNumberFieldEditor()}>
|
||||
Open index pattern field editor to give it a try.
|
||||
Currency formatter and its custom editor are integrated with data views. It can be applied
|
||||
to any <EuiCode>numeric</EuiCode> field of any data view.{' '}
|
||||
<EuiLink onClick={() => props.deps.openDateViewNumberFieldEditor()}>
|
||||
Open date view field editor to give it a try.
|
||||
</EuiLink>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
|
|
|
@ -45,29 +45,29 @@ export class FieldFormatsExamplePlugin implements Plugin<void, void, SetupDeps,
|
|||
registerExampleFormatEditor(deps.dataViewFieldEditor);
|
||||
|
||||
// just for demonstration purposes:
|
||||
// opens a field editor using default index pattern and first number field
|
||||
const openIndexPatternNumberFieldEditor = async () => {
|
||||
// opens a field editor using default data view and first number field
|
||||
const openDateViewNumberFieldEditor = async () => {
|
||||
const [, plugins] = await core.getStartServices();
|
||||
const indexPattern = await plugins.data.indexPatterns.getDefault();
|
||||
if (!indexPattern) {
|
||||
alert('Creating at least one index pattern to continue with this example');
|
||||
const dataView = await plugins.data.dataViews.getDefault();
|
||||
if (!dataView) {
|
||||
alert('Create at least one data view to continue with this example');
|
||||
return;
|
||||
}
|
||||
|
||||
const numberField = indexPattern
|
||||
.getNonScriptedFields()
|
||||
.find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER);
|
||||
const numberField = dataView.fields
|
||||
.getAll()
|
||||
.find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER && !f.scripted);
|
||||
|
||||
if (!numberField) {
|
||||
alert(
|
||||
'Default index pattern needs at least a single field of type `number` to continue with this example'
|
||||
'Default data view needs at least a single field of type `number` to continue with this example'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
plugins.dataViewFieldEditor.openEditor({
|
||||
ctx: {
|
||||
dataView: indexPattern,
|
||||
dataView,
|
||||
},
|
||||
fieldName: numberField.name,
|
||||
});
|
||||
|
@ -81,7 +81,7 @@ export class FieldFormatsExamplePlugin implements Plugin<void, void, SetupDeps,
|
|||
async mount({ element }: AppMountParameters) {
|
||||
const [, plugins] = await core.getStartServices();
|
||||
ReactDOM.render(
|
||||
<App deps={{ fieldFormats: plugins.fieldFormats, openIndexPatternNumberFieldEditor }} />,
|
||||
<App deps={{ fieldFormats: plugins.fieldFormats, openDateViewNumberFieldEditor }} />,
|
||||
element
|
||||
);
|
||||
return () => ReactDOM.unmountComponentAtNode(element);
|
||||
|
|
|
@ -41,11 +41,10 @@ import { PLUGIN_ID, PLUGIN_NAME, SERVER_SEARCH_ROUTE_PATH } from '../../common';
|
|||
import {
|
||||
DataPublicPluginStart,
|
||||
IKibanaSearchResponse,
|
||||
IndexPattern,
|
||||
IndexPatternField,
|
||||
isCompleteResponse,
|
||||
isErrorResponse,
|
||||
} from '../../../../src/plugins/data/public';
|
||||
import type { DataViewField, DataView } from '../../../../src/plugins/data_views/public';
|
||||
import { IMyStrategyResponse } from '../../common/types';
|
||||
import { AbortError } from '../../../../src/plugins/kibana_utils/common';
|
||||
|
||||
|
@ -56,22 +55,22 @@ interface SearchExamplesAppDeps {
|
|||
data: DataPublicPluginStart;
|
||||
}
|
||||
|
||||
function getNumeric(fields?: IndexPatternField[]) {
|
||||
function getNumeric(fields?: DataViewField[]) {
|
||||
if (!fields) return [];
|
||||
return fields?.filter((f) => f.type === 'number' && f.aggregatable);
|
||||
}
|
||||
|
||||
function getAggregatableStrings(fields?: IndexPatternField[]) {
|
||||
function getAggregatableStrings(fields?: DataViewField[]) {
|
||||
if (!fields) return [];
|
||||
return fields?.filter((f) => f.type === 'string' && f.aggregatable);
|
||||
}
|
||||
|
||||
function formatFieldToComboBox(field?: IndexPatternField | null) {
|
||||
function formatFieldToComboBox(field?: DataViewField | null) {
|
||||
if (!field) return [];
|
||||
return formatFieldsToComboBox([field]);
|
||||
}
|
||||
|
||||
function formatFieldsToComboBox(fields?: IndexPatternField[]) {
|
||||
function formatFieldsToComboBox(fields?: DataViewField[]) {
|
||||
if (!fields) return [];
|
||||
|
||||
return fields?.map((field) => {
|
||||
|
@ -93,14 +92,14 @@ export const SearchExamplesApp = ({
|
|||
const [timeTook, setTimeTook] = useState<number | undefined>();
|
||||
const [total, setTotal] = useState<number>(100);
|
||||
const [loaded, setLoaded] = useState<number>(0);
|
||||
const [indexPattern, setIndexPattern] = useState<IndexPattern | null>();
|
||||
const [fields, setFields] = useState<IndexPatternField[]>();
|
||||
const [selectedFields, setSelectedFields] = useState<IndexPatternField[]>([]);
|
||||
const [dataView, setDataView] = useState<DataView | null>();
|
||||
const [fields, setFields] = useState<DataViewField[]>();
|
||||
const [selectedFields, setSelectedFields] = useState<DataViewField[]>([]);
|
||||
const [selectedNumericField, setSelectedNumericField] = useState<
|
||||
IndexPatternField | null | undefined
|
||||
DataViewField | null | undefined
|
||||
>();
|
||||
const [selectedBucketField, setSelectedBucketField] = useState<
|
||||
IndexPatternField | null | undefined
|
||||
DataViewField | null | undefined
|
||||
>();
|
||||
const [request, setRequest] = useState<Record<string, any>>({});
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
@ -115,20 +114,20 @@ export const SearchExamplesApp = ({
|
|||
setTimeTook(response.rawResponse.took);
|
||||
}
|
||||
|
||||
// Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted.
|
||||
// Fetch the default data view using the `data.dataViews` service, as the component is mounted.
|
||||
useEffect(() => {
|
||||
const setDefaultIndexPattern = async () => {
|
||||
const defaultIndexPattern = await data.indexPatterns.getDefault();
|
||||
setIndexPattern(defaultIndexPattern);
|
||||
const setDefaultDataView = async () => {
|
||||
const defaultDataView = await data.dataViews.getDefault();
|
||||
setDataView(defaultDataView);
|
||||
};
|
||||
|
||||
setDefaultIndexPattern();
|
||||
setDefaultDataView();
|
||||
}, [data]);
|
||||
|
||||
// Update the fields list every time the index pattern is modified.
|
||||
// Update the fields list every time the data view is modified.
|
||||
useEffect(() => {
|
||||
setFields(indexPattern?.fields);
|
||||
}, [indexPattern]);
|
||||
setFields(dataView?.fields);
|
||||
}, [dataView]);
|
||||
useEffect(() => {
|
||||
setSelectedBucketField(fields?.length ? getAggregatableStrings(fields)[0] : null);
|
||||
setSelectedNumericField(fields?.length ? getNumeric(fields)[0] : null);
|
||||
|
@ -140,10 +139,10 @@ export const SearchExamplesApp = ({
|
|||
addWarning: boolean = false,
|
||||
addError: boolean = false
|
||||
) => {
|
||||
if (!indexPattern || !selectedNumericField) return;
|
||||
if (!dataView || !selectedNumericField) return;
|
||||
|
||||
// Construct the query portion of the search request
|
||||
const query = data.query.getEsQuery(indexPattern);
|
||||
const query = data.query.getEsQuery(dataView);
|
||||
|
||||
if (addWarning) {
|
||||
query.bool.must.push({
|
||||
|
@ -151,7 +150,7 @@ export const SearchExamplesApp = ({
|
|||
error_query: {
|
||||
indices: [
|
||||
{
|
||||
name: indexPattern.title,
|
||||
name: dataView.title,
|
||||
error_type: 'warning',
|
||||
message: 'Watch out!',
|
||||
},
|
||||
|
@ -165,7 +164,7 @@ export const SearchExamplesApp = ({
|
|||
error_query: {
|
||||
indices: [
|
||||
{
|
||||
name: indexPattern.title,
|
||||
name: dataView.title,
|
||||
error_type: 'exception',
|
||||
message: 'Watch out!',
|
||||
},
|
||||
|
@ -176,11 +175,11 @@ export const SearchExamplesApp = ({
|
|||
|
||||
// Construct the aggregations portion of the search request by using the `data.search.aggs` service.
|
||||
const aggs = [{ type: 'avg', params: { field: selectedNumericField!.name } }];
|
||||
const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl();
|
||||
const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl();
|
||||
|
||||
const req = {
|
||||
params: {
|
||||
index: indexPattern.title,
|
||||
index: dataView.title,
|
||||
body: {
|
||||
aggs: aggsDsl,
|
||||
query,
|
||||
|
@ -264,11 +263,11 @@ export const SearchExamplesApp = ({
|
|||
};
|
||||
|
||||
const doSearchSourceSearch = async (otherBucket: boolean) => {
|
||||
if (!indexPattern) return;
|
||||
if (!dataView) return;
|
||||
|
||||
const query = data.query.queryString.getQuery();
|
||||
const filters = data.query.filterManager.getFilters();
|
||||
const timefilter = data.query.timefilter.timefilter.createFilter(indexPattern);
|
||||
const timefilter = data.query.timefilter.timefilter.createFilter(dataView);
|
||||
if (timefilter) {
|
||||
filters.push(timefilter);
|
||||
}
|
||||
|
@ -277,7 +276,7 @@ export const SearchExamplesApp = ({
|
|||
const searchSource = await data.search.searchSource.create();
|
||||
|
||||
searchSource
|
||||
.setField('index', indexPattern)
|
||||
.setField('index', dataView)
|
||||
.setField('filter', filters)
|
||||
.setField('query', query)
|
||||
.setField('fields', selectedFields.length ? selectedFields.map((f) => f.name) : [''])
|
||||
|
@ -296,7 +295,7 @@ export const SearchExamplesApp = ({
|
|||
aggDef.push({ type: 'avg', params: { field: selectedNumericField.name } });
|
||||
}
|
||||
if (aggDef.length > 0) {
|
||||
const ac = data.search.aggs.createAggConfigs(indexPattern, aggDef);
|
||||
const ac = data.search.aggs.createAggConfigs(dataView, aggDef);
|
||||
searchSource.setField('aggs', ac);
|
||||
}
|
||||
|
||||
|
@ -407,14 +406,14 @@ export const SearchExamplesApp = ({
|
|||
};
|
||||
|
||||
const onServerClickHandler = async () => {
|
||||
if (!indexPattern || !selectedNumericField) return;
|
||||
if (!dataView || !selectedNumericField) return;
|
||||
const abortController = new AbortController();
|
||||
setAbortController(abortController);
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const res = await http.get(SERVER_SEARCH_ROUTE_PATH, {
|
||||
query: {
|
||||
index: indexPattern.title,
|
||||
index: dataView.title,
|
||||
field: selectedNumericField!.name,
|
||||
},
|
||||
signal: abortController.signal,
|
||||
|
@ -510,22 +509,26 @@ export const SearchExamplesApp = ({
|
|||
appName={PLUGIN_ID}
|
||||
showSearchBar={true}
|
||||
useDefaultBehaviors={true}
|
||||
indexPatterns={indexPattern ? [indexPattern] : undefined}
|
||||
indexPatterns={dataView ? [dataView] : undefined}
|
||||
/>
|
||||
<EuiFlexGrid columns={4}>
|
||||
<EuiFlexItem>
|
||||
<EuiFormLabel>Index Pattern</EuiFormLabel>
|
||||
<EuiFormLabel>Data view</EuiFormLabel>
|
||||
<IndexPatternSelect
|
||||
placeholder={i18n.translate('searchSessionExample.selectIndexPatternPlaceholder', {
|
||||
defaultMessage: 'Select index pattern',
|
||||
placeholder={i18n.translate('searchSessionExample.selectDataViewPlaceholder', {
|
||||
defaultMessage: 'Select data view',
|
||||
})}
|
||||
indexPatternId={indexPattern?.id || ''}
|
||||
onChange={async (newIndexPatternId: any) => {
|
||||
const newIndexPattern = await data.indexPatterns.get(newIndexPatternId);
|
||||
setIndexPattern(newIndexPattern);
|
||||
indexPatternId={dataView?.id || ''}
|
||||
onChange={async (dataViewId?: string) => {
|
||||
if (dataViewId) {
|
||||
const newDataView = await data.dataViews.get(dataViewId);
|
||||
setDataView(newDataView);
|
||||
} else {
|
||||
setDataView(undefined);
|
||||
}
|
||||
}}
|
||||
isClearable={false}
|
||||
data-test-subj="indexPatternSelector"
|
||||
data-test-subj="dataViewSelector"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
|
@ -536,7 +539,7 @@ export const SearchExamplesApp = ({
|
|||
singleSelection={true}
|
||||
onChange={(option) => {
|
||||
if (option.length) {
|
||||
const fld = indexPattern?.getFieldByName(option[0].label);
|
||||
const fld = dataView?.getFieldByName(option[0].label);
|
||||
setSelectedBucketField(fld || null);
|
||||
} else {
|
||||
setSelectedBucketField(null);
|
||||
|
@ -554,7 +557,7 @@ export const SearchExamplesApp = ({
|
|||
singleSelection={true}
|
||||
onChange={(option) => {
|
||||
if (option.length) {
|
||||
const fld = indexPattern?.getFieldByName(option[0].label);
|
||||
const fld = dataView?.getFieldByName(option[0].label);
|
||||
setSelectedNumericField(fld || null);
|
||||
} else {
|
||||
setSelectedNumericField(null);
|
||||
|
@ -572,9 +575,9 @@ export const SearchExamplesApp = ({
|
|||
singleSelection={false}
|
||||
onChange={(option) => {
|
||||
const flds = option
|
||||
.map((opt) => indexPattern?.getFieldByName(opt?.label))
|
||||
.map((opt) => dataView?.getFieldByName(opt?.label))
|
||||
.filter((f) => f);
|
||||
setSelectedFields(flds.length ? (flds as IndexPatternField[]) : []);
|
||||
setSelectedFields(flds.length ? (flds as DataViewField[]) : []);
|
||||
}}
|
||||
sortMatchesBy="startsWith"
|
||||
/>
|
||||
|
@ -590,9 +593,8 @@ export const SearchExamplesApp = ({
|
|||
</EuiTitle>
|
||||
<EuiText>
|
||||
If you want to fetch data from Elasticsearch, you can use the different services
|
||||
provided by the <EuiCode>data</EuiCode> plugin. These help you get the index pattern
|
||||
and search bar configuration, format them into a DSL query and send it to
|
||||
Elasticsearch.
|
||||
provided by the <EuiCode>data</EuiCode> plugin. These help you get the data view and
|
||||
search bar configuration, format them into a DSL query and send it to Elasticsearch.
|
||||
<EuiSpacer />
|
||||
<EuiButtonEmpty size="xs" onClick={onClickHandler} iconType="play">
|
||||
<FormattedMessage
|
||||
|
|
|
@ -43,14 +43,13 @@ import {
|
|||
DataPublicPluginStart,
|
||||
IEsSearchRequest,
|
||||
IEsSearchResponse,
|
||||
IndexPattern,
|
||||
IndexPatternField,
|
||||
isCompleteResponse,
|
||||
isErrorResponse,
|
||||
QueryState,
|
||||
SearchSessionState,
|
||||
TimeRange,
|
||||
} from '../../../../src/plugins/data/public';
|
||||
import type { DataView, DataViewField } from '../../../../src/plugins/data_views/public';
|
||||
import {
|
||||
createStateContainer,
|
||||
useContainerState,
|
||||
|
@ -77,7 +76,7 @@ enum DemoStep {
|
|||
}
|
||||
|
||||
interface State extends QueryState {
|
||||
indexPatternId?: string;
|
||||
dataViewId?: string;
|
||||
numericFieldName?: string;
|
||||
|
||||
/**
|
||||
|
@ -123,10 +122,10 @@ export const SearchSessionsExampleApp = ({
|
|||
|
||||
const {
|
||||
numericFieldName,
|
||||
indexPattern,
|
||||
dataView,
|
||||
selectedField,
|
||||
fields,
|
||||
setIndexPattern,
|
||||
setDataView,
|
||||
setNumericFieldName,
|
||||
state,
|
||||
} = useAppState({ data });
|
||||
|
@ -141,14 +140,14 @@ export const SearchSessionsExampleApp = ({
|
|||
time: data.query.timefilter.timefilter.getTime(),
|
||||
filters: data.query.filterManager.getFilters(),
|
||||
query: data.query.queryString.getQuery(),
|
||||
indexPatternId: indexPattern?.id,
|
||||
dataViewId: dataView?.id,
|
||||
numericFieldName,
|
||||
},
|
||||
restoreState: {
|
||||
time: data.query.timefilter.timefilter.getAbsoluteTime(),
|
||||
filters: data.query.filterManager.getFilters(),
|
||||
query: data.query.queryString.getQuery(),
|
||||
indexPatternId: indexPattern?.id,
|
||||
dataViewId: dataView?.id,
|
||||
numericFieldName,
|
||||
searchSessionId: data.search.session.getSessionId(),
|
||||
},
|
||||
|
@ -160,7 +159,7 @@ export const SearchSessionsExampleApp = ({
|
|||
data.query.queryString,
|
||||
data.query.timefilter.timefilter,
|
||||
data.search.session,
|
||||
indexPattern?.id,
|
||||
dataView?.id,
|
||||
numericFieldName,
|
||||
]);
|
||||
|
||||
|
@ -198,11 +197,11 @@ export const SearchSessionsExampleApp = ({
|
|||
|
||||
const search = useCallback(
|
||||
(restoreSearchSessionId?: string) => {
|
||||
if (!indexPattern) return;
|
||||
if (!dataView) return;
|
||||
if (!numericFieldName) return;
|
||||
setIsSearching(true);
|
||||
const requestId = ++nextRequestIdRef.current;
|
||||
doSearch({ indexPattern, numericFieldName, restoreSearchSessionId }, { data, notifications })
|
||||
doSearch({ dataView, numericFieldName, restoreSearchSessionId }, { data, notifications })
|
||||
.then(({ response: res, request: req, tookMs: _tookMs }) => {
|
||||
if (requestId !== nextRequestIdRef.current) return; // no longer interested in this result
|
||||
if (restoreSearchSessionId) {
|
||||
|
@ -220,7 +219,7 @@ export const SearchSessionsExampleApp = ({
|
|||
setIsSearching(false);
|
||||
});
|
||||
},
|
||||
[data, notifications, indexPattern, numericFieldName]
|
||||
[data, notifications, dataView, numericFieldName]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -243,9 +242,9 @@ export const SearchSessionsExampleApp = ({
|
|||
<EuiSpacer />
|
||||
</>
|
||||
)}
|
||||
{!indexPattern && (
|
||||
{!dataView && (
|
||||
<>
|
||||
<NoIndexPatternsCallout />
|
||||
<NoDataViewsCallout />
|
||||
<EuiSpacer />
|
||||
</>
|
||||
)}
|
||||
|
@ -280,26 +279,23 @@ export const SearchSessionsExampleApp = ({
|
|||
appName={PLUGIN_ID}
|
||||
showSearchBar={true}
|
||||
useDefaultBehaviors={true}
|
||||
indexPatterns={indexPattern ? [indexPattern] : undefined}
|
||||
indexPatterns={dataView ? [dataView] : undefined}
|
||||
onQuerySubmit={reset}
|
||||
/>
|
||||
<EuiFlexGroup justifyContent={'flexStart'}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFormLabel>Index Pattern</EuiFormLabel>
|
||||
<EuiFormLabel>Data view</EuiFormLabel>
|
||||
<IndexPatternSelect
|
||||
placeholder={i18n.translate(
|
||||
'searchSessionExample.selectIndexPatternPlaceholder',
|
||||
{
|
||||
defaultMessage: 'Select index pattern',
|
||||
}
|
||||
)}
|
||||
indexPatternId={indexPattern?.id ?? ''}
|
||||
placeholder={i18n.translate('searchSessionExample.selectDataViewPlaceholder', {
|
||||
defaultMessage: 'Select data view',
|
||||
})}
|
||||
indexPatternId={dataView?.id ?? ''}
|
||||
onChange={(id) => {
|
||||
if (!id) return;
|
||||
setIndexPattern(id);
|
||||
setDataView(id);
|
||||
}}
|
||||
isClearable={false}
|
||||
data-test-subj="indexPatternSelector"
|
||||
data-test-subj="dataViewSelector"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -309,7 +305,7 @@ export const SearchSessionsExampleApp = ({
|
|||
selectedOptions={formatFieldToComboBox(selectedField)}
|
||||
singleSelection={true}
|
||||
onChange={(option) => {
|
||||
const fld = indexPattern?.getFieldByName(option[0].label);
|
||||
const fld = dataView?.getFieldByName(option[0].label);
|
||||
if (!fld) return;
|
||||
setNumericFieldName(fld?.name);
|
||||
}}
|
||||
|
@ -336,7 +332,7 @@ export const SearchSessionsExampleApp = ({
|
|||
size="xs"
|
||||
onClick={() => search()}
|
||||
iconType="play"
|
||||
disabled={isSearching || !indexPattern || !numericFieldName}
|
||||
disabled={isSearching || !dataView || !numericFieldName}
|
||||
data-test-subj={'startSearch'}
|
||||
>
|
||||
Start the search from low-level client (data.search.search)
|
||||
|
@ -540,7 +536,7 @@ function SearchInspector({
|
|||
|
||||
function useAppState({ data }: { data: DataPublicPluginStart }) {
|
||||
const stateContainer = useMemo(() => {
|
||||
const { filters, time, searchSessionId, numericFieldName, indexPatternId, query } =
|
||||
const { filters, time, searchSessionId, numericFieldName, dataViewId, query } =
|
||||
getInitialStateFromUrl();
|
||||
|
||||
if (filters) {
|
||||
|
@ -558,7 +554,7 @@ function useAppState({ data }: { data: DataPublicPluginStart }) {
|
|||
return createStateContainer<State>({
|
||||
restoreSessionId: searchSessionId,
|
||||
numericFieldName,
|
||||
indexPatternId,
|
||||
dataViewId,
|
||||
});
|
||||
}, [data.query.filterManager, data.query.queryString, data.query.timefilter.timefilter]);
|
||||
const setState = useCallback(
|
||||
|
@ -575,78 +571,78 @@ function useAppState({ data }: { data: DataPublicPluginStart }) {
|
|||
});
|
||||
}, [stateContainer, data.query]);
|
||||
|
||||
const [fields, setFields] = useState<IndexPatternField[]>();
|
||||
const [indexPattern, setIndexPattern] = useState<IndexPattern | null>();
|
||||
const [fields, setFields] = useState<DataViewField[]>();
|
||||
const [dataView, setDataView] = useState<DataView | null>();
|
||||
|
||||
// Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted.
|
||||
// Fetch the default data view using the `data.dataViews` service, as the component is mounted.
|
||||
useEffect(() => {
|
||||
let canceled = false;
|
||||
const loadIndexPattern = async () => {
|
||||
const loadDataView = async () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('Loading default index pattern');
|
||||
let loadedIndexPattern = state.indexPatternId
|
||||
? await data.indexPatterns.get(state.indexPatternId)
|
||||
: await data.indexPatterns.getDefault();
|
||||
if (!loadedIndexPattern) {
|
||||
// try to find any available index pattern
|
||||
const [id] = await data.indexPatterns.getIds(true);
|
||||
console.warn('Loading default data view');
|
||||
let loadedDataView = state.dataViewId
|
||||
? await data.dataViews.get(state.dataViewId)
|
||||
: await data.dataViews.getDefault();
|
||||
if (!loadedDataView) {
|
||||
// try to find any available data view
|
||||
const [id] = await data.dataViews.getIds(true);
|
||||
if (id) {
|
||||
loadedIndexPattern = await data.indexPatterns.get(id);
|
||||
loadedDataView = await data.dataViews.get(id);
|
||||
}
|
||||
}
|
||||
if (canceled) return;
|
||||
if (!loadedIndexPattern) {
|
||||
if (!loadedDataView) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('No index patterns to pick from');
|
||||
console.warn('No data view to pick from');
|
||||
return;
|
||||
}
|
||||
if (!state.indexPatternId) {
|
||||
if (!state.dataViewId) {
|
||||
setState({
|
||||
indexPatternId: loadedIndexPattern.id,
|
||||
dataViewId: loadedDataView.id,
|
||||
});
|
||||
}
|
||||
|
||||
setIndexPattern(loadedIndexPattern);
|
||||
setDataView(loadedDataView);
|
||||
};
|
||||
|
||||
loadIndexPattern();
|
||||
loadDataView();
|
||||
return () => {
|
||||
canceled = true;
|
||||
};
|
||||
}, [data, setState, state.indexPatternId]);
|
||||
}, [data, setState, state.dataViewId]);
|
||||
|
||||
// Update the fields list every time the index pattern is modified.
|
||||
// Update the fields list every time the data view is modified.
|
||||
useEffect(() => {
|
||||
setFields(indexPattern?.fields);
|
||||
}, [indexPattern]);
|
||||
setFields(dataView?.fields);
|
||||
}, [dataView]);
|
||||
useEffect(() => {
|
||||
if (state.numericFieldName) return;
|
||||
setState({ numericFieldName: fields?.length ? getNumeric(fields)[0]?.name : undefined });
|
||||
}, [setState, fields, state.numericFieldName]);
|
||||
|
||||
const selectedField: IndexPatternField | undefined = useMemo(
|
||||
() => indexPattern?.fields.find((field) => field.name === state.numericFieldName),
|
||||
[indexPattern?.fields, state.numericFieldName]
|
||||
const selectedField: DataViewField | undefined = useMemo(
|
||||
() => dataView?.fields.find((field) => field.name === state.numericFieldName),
|
||||
[dataView?.fields, state.numericFieldName]
|
||||
);
|
||||
|
||||
return {
|
||||
selectedField,
|
||||
indexPattern,
|
||||
dataView,
|
||||
numericFieldName: state.numericFieldName,
|
||||
fields,
|
||||
setNumericFieldName: (field: string) => setState({ numericFieldName: field }),
|
||||
setIndexPattern: (indexPatternId: string) => setState({ indexPatternId }),
|
||||
setDataView: (dataViewId: string) => setState({ dataViewId }),
|
||||
state,
|
||||
};
|
||||
}
|
||||
|
||||
function doSearch(
|
||||
{
|
||||
indexPattern,
|
||||
dataView,
|
||||
numericFieldName,
|
||||
restoreSearchSessionId,
|
||||
}: {
|
||||
indexPattern: IndexPattern;
|
||||
dataView: DataView;
|
||||
numericFieldName: string;
|
||||
restoreSearchSessionId?: string;
|
||||
},
|
||||
|
@ -655,7 +651,7 @@ function doSearch(
|
|||
notifications,
|
||||
}: { data: DataPublicPluginStart; notifications: CoreStart['notifications'] }
|
||||
): Promise<{ request: IEsSearchRequest; response: IEsSearchResponse; tookMs?: number }> {
|
||||
if (!indexPattern) return Promise.reject('Select an index patten');
|
||||
if (!dataView) return Promise.reject('Select a data view');
|
||||
if (!numericFieldName) return Promise.reject('Select a field to aggregate on');
|
||||
|
||||
// start a new session or restore an existing one
|
||||
|
@ -668,7 +664,7 @@ function doSearch(
|
|||
const sessionId = restoreSearchSessionId ? restoreSearchSessionId : data.search.session.start();
|
||||
|
||||
// Construct the query portion of the search request
|
||||
const query = data.query.getEsQuery(indexPattern, restoreTimeRange);
|
||||
const query = data.query.getEsQuery(dataView, restoreTimeRange);
|
||||
|
||||
// Construct the aggregations portion of the search request by using the `data.search.aggs` service.
|
||||
|
||||
|
@ -679,11 +675,11 @@ function doSearch(
|
|||
]
|
||||
: [{ type: 'avg', params: { field: numericFieldName } }];
|
||||
|
||||
const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl();
|
||||
const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl();
|
||||
|
||||
const req = {
|
||||
params: {
|
||||
index: indexPattern.title,
|
||||
index: dataView.title,
|
||||
body: {
|
||||
aggs: aggsDsl,
|
||||
query,
|
||||
|
@ -728,17 +724,17 @@ function doSearch(
|
|||
.toPromise();
|
||||
}
|
||||
|
||||
function getNumeric(fields?: IndexPatternField[]) {
|
||||
function getNumeric(fields?: DataViewField[]) {
|
||||
if (!fields) return [];
|
||||
return fields?.filter((f) => f.type === 'number' && f.aggregatable);
|
||||
}
|
||||
|
||||
function formatFieldToComboBox(field?: IndexPatternField | null) {
|
||||
function formatFieldToComboBox(field?: DataViewField | null) {
|
||||
if (!field) return [];
|
||||
return formatFieldsToComboBox([field]);
|
||||
}
|
||||
|
||||
function formatFieldsToComboBox(fields?: IndexPatternField[]) {
|
||||
function formatFieldsToComboBox(fields?: DataViewField[]) {
|
||||
if (!fields) return [];
|
||||
|
||||
return fields?.map((field) => {
|
||||
|
@ -781,10 +777,10 @@ function NoShardDelayCallout() {
|
|||
);
|
||||
}
|
||||
|
||||
function NoIndexPatternsCallout() {
|
||||
function NoDataViewsCallout() {
|
||||
return (
|
||||
<EuiCallOut title={<>Missing index patterns!</>} color="warning" iconType="help">
|
||||
<p>This demo requires at least one index pattern.</p>
|
||||
<EuiCallOut title={<>Missing data views!</>} color="warning" iconType="help">
|
||||
<p>This demo requires at least one data view.</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
|
||||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
import { esFilters, Filter, Query, TimeRange } from '../../../../src/plugins/data/public';
|
||||
import { Filter, Query, isFilterPinned } from '@kbn/es-query';
|
||||
import type { TimeRange } from '../../../../src/plugins/data/public';
|
||||
import { getStatesFromKbnUrl, setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public';
|
||||
import { LocatorDefinition } from '../../../../src/plugins/share/common';
|
||||
|
||||
|
@ -19,7 +20,7 @@ export const SEARCH_SESSIONS_EXAMPLES_APP_LOCATOR = 'SEARCH_SESSIONS_EXAMPLES_AP
|
|||
export interface AppUrlState extends SerializableRecord {
|
||||
filters?: Filter[];
|
||||
query?: Query;
|
||||
indexPatternId?: string;
|
||||
dataViewId?: string;
|
||||
numericFieldName?: string;
|
||||
searchSessionId?: string;
|
||||
}
|
||||
|
@ -46,8 +47,8 @@ export class SearchSessionsExamplesAppLocatorDefinition
|
|||
STATE_STORAGE_KEY,
|
||||
{
|
||||
query: params.query,
|
||||
filters: params.filters?.filter((f) => !esFilters.isFilterPinned(f)),
|
||||
indexPatternId: params.indexPatternId,
|
||||
filters: params.filters?.filter((f) => !isFilterPinned(f)),
|
||||
dataViewId: params.dataViewId,
|
||||
numericFieldName: params.numericFieldName,
|
||||
searchSessionId: params.searchSessionId,
|
||||
} as AppUrlState,
|
||||
|
@ -59,7 +60,7 @@ export class SearchSessionsExamplesAppLocatorDefinition
|
|||
GLOBAL_STATE_STORAGE_KEY,
|
||||
{
|
||||
time: params.time,
|
||||
filters: params.filters?.filter((f) => esFilters.isFilterPinned(f)),
|
||||
filters: params.filters?.filter((f) => isFilterPinned(f)),
|
||||
} as GlobalUrlState,
|
||||
{ useHash: false, storeInHashQuery: false },
|
||||
url
|
||||
|
@ -75,7 +76,7 @@ export class SearchSessionsExamplesAppLocatorDefinition
|
|||
|
||||
export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams {
|
||||
const {
|
||||
_a: { numericFieldName, indexPatternId, searchSessionId, filters: aFilters, query } = {},
|
||||
_a: { numericFieldName, dataViewId, searchSessionId, filters: aFilters, query } = {},
|
||||
_g: { filters: gFilters, time } = {},
|
||||
} = getStatesFromKbnUrl<{ _a: AppUrlState; _g: GlobalUrlState }>(
|
||||
window.location.href,
|
||||
|
@ -90,7 +91,7 @@ export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams
|
|||
searchSessionId,
|
||||
time,
|
||||
filters: [...(gFilters ?? []), ...(aFilters ?? [])],
|
||||
indexPatternId,
|
||||
dataViewId,
|
||||
query,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"references": [
|
||||
{ "path": "../../src/core/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data_views/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/kibana_utils/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/kibana_react/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/navigation/tsconfig.json" },
|
||||
|
|
|
@ -18,19 +18,18 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { Filter, FilterStateStore } from '@kbn/es-query';
|
||||
import { CoreStart } from 'kibana/public';
|
||||
import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public';
|
||||
|
||||
import {
|
||||
connectToQueryState,
|
||||
DataPublicPluginStart,
|
||||
esFilters,
|
||||
Filter,
|
||||
IndexPattern,
|
||||
Query,
|
||||
QueryState,
|
||||
syncQueryStateWithUrl,
|
||||
} from '../../../../src/plugins/data/public';
|
||||
import type { DataView } from '../../../../src/plugins/data_views/public';
|
||||
import {
|
||||
BaseStateContainer,
|
||||
createStateContainer,
|
||||
|
@ -73,13 +72,9 @@ export const App = ({
|
|||
useGlobalStateSyncing(data.query, kbnUrlStateStorage);
|
||||
useAppStateSyncing(appStateContainer, data.query, kbnUrlStateStorage);
|
||||
|
||||
const indexPattern = useIndexPattern(data);
|
||||
if (!indexPattern)
|
||||
return (
|
||||
<div>
|
||||
No index pattern found. Please create an index pattern before trying this example...
|
||||
</div>
|
||||
);
|
||||
const dataView = useDataView(data);
|
||||
if (!dataView)
|
||||
return <div>No data view found. Please create a data view before trying this example...</div>;
|
||||
|
||||
// Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract.
|
||||
return (
|
||||
|
@ -102,7 +97,7 @@ export const App = ({
|
|||
<navigation.ui.TopNavMenu
|
||||
appName={'Example'}
|
||||
showSearchBar={true}
|
||||
indexPatterns={[indexPattern]}
|
||||
indexPatterns={[dataView]}
|
||||
useDefaultBehaviors={true}
|
||||
showSaveQuery={true}
|
||||
/>
|
||||
|
@ -126,19 +121,19 @@ export const App = ({
|
|||
);
|
||||
};
|
||||
|
||||
function useIndexPattern(data: DataPublicPluginStart) {
|
||||
const [indexPattern, setIndexPattern] = useState<IndexPattern>();
|
||||
function useDataView(data: DataPublicPluginStart) {
|
||||
const [dataView, setDataView] = useState<DataView>();
|
||||
useEffect(() => {
|
||||
const fetchIndexPattern = async () => {
|
||||
const defaultIndexPattern = await data.indexPatterns.getDefault();
|
||||
if (defaultIndexPattern) {
|
||||
setIndexPattern(defaultIndexPattern);
|
||||
const fetchDataView = async () => {
|
||||
const defaultDataView = await data.dataViews.getDefault();
|
||||
if (defaultDataView) {
|
||||
setDataView(defaultDataView);
|
||||
}
|
||||
};
|
||||
fetchIndexPattern();
|
||||
}, [data.indexPatterns]);
|
||||
fetchDataView();
|
||||
}, [data.dataViews]);
|
||||
|
||||
return indexPattern;
|
||||
return dataView;
|
||||
}
|
||||
|
||||
function useGlobalStateSyncing(
|
||||
|
@ -167,7 +162,7 @@ function useAppStateSyncing<AppState extends QueryState>(
|
|||
const stopSyncingQueryAppStateWithStateContainer = connectToQueryState(
|
||||
query,
|
||||
appStateContainer,
|
||||
{ filters: esFilters.FilterStateStore.APP_STATE, query: true }
|
||||
{ filters: FilterStateStore.APP_STATE, query: true }
|
||||
);
|
||||
|
||||
// sets up syncing app state container with url
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
{ "path": "../../src/plugins/kibana_react/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/navigation/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data/tsconfig.json" },
|
||||
{ "path": "../../src/plugins/data_views/tsconfig.json" },
|
||||
{ "path": "../developer_examples/tsconfig.json" },
|
||||
]
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default async function ({ readConfigFile }) {
|
|||
require.resolve('./state_sync'),
|
||||
require.resolve('./routing'),
|
||||
require.resolve('./expressions_explorer'),
|
||||
require.resolve('./index_pattern_field_editor_example'),
|
||||
require.resolve('./data_view_field_editor_example'),
|
||||
require.resolve('./field_formats'),
|
||||
require.resolve('./partial_results'),
|
||||
],
|
||||
|
|
|
@ -13,8 +13,8 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('', () => {
|
||||
it('finds an index pattern', async () => {
|
||||
await testSubjects.existOrFail('indexPatternTitle');
|
||||
it('finds a data view', async () => {
|
||||
await testSubjects.existOrFail('dataViewTitle');
|
||||
});
|
||||
it('opens the field editor', async () => {
|
||||
await testSubjects.click('addField');
|
|
@ -19,7 +19,7 @@ export default function ({
|
|||
const es = getService('es');
|
||||
const PageObjects = getPageObjects(['common', 'header', 'settings']);
|
||||
|
||||
describe('index pattern field editor example', function () {
|
||||
describe('data view field editor example', function () {
|
||||
this.tags('ciGroup2');
|
||||
before(async () => {
|
||||
await esArchiver.emptyKibanaIndex();
|
||||
|
@ -32,9 +32,9 @@ export default function ({
|
|||
|
||||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.createIndexPattern('blogs', null);
|
||||
await PageObjects.common.navigateToApp('indexPatternFieldEditorExample');
|
||||
await PageObjects.common.navigateToApp('dataViewFieldEditorExample');
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./index_pattern_field_editor_example'));
|
||||
loadTestFile(require.resolve('./data_view_field_editor_example'));
|
||||
});
|
||||
}
|
|
@ -21,7 +21,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
before(async function () {
|
||||
await PageObjects.common.navigateToApp(appId, { insertTimestamp: false });
|
||||
await comboBox.setCustom('indexPatternSelector', 'logstash-*');
|
||||
await comboBox.setCustom('dataViewSelector', 'logstash-*');
|
||||
await comboBox.set('searchBucketField', 'geo.src');
|
||||
await comboBox.set('searchMetricField', 'memory');
|
||||
await PageObjects.timePicker.setAbsoluteRange(
|
||||
|
|
|
@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should start search, save session, restore session using "restore" button', async () => {
|
||||
await comboBox.setCustom('indexPatternSelector', 'logstash-*');
|
||||
await comboBox.setCustom('dataViewSelector', 'logstash-*');
|
||||
await comboBox.setCustom('searchMetricField', 'bytes');
|
||||
await testSubjects.clickWhenNotDisabled('startSearch');
|
||||
await testSubjects.find('searchResults-1');
|
||||
|
|
|
@ -32,7 +32,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
before(async function () {
|
||||
await PageObjects.common.navigateToApp(appId, { insertTimestamp: false });
|
||||
await comboBox.setCustom('indexPatternSelector', 'logstash-*');
|
||||
await comboBox.setCustom('dataViewSelector', 'logstash-*');
|
||||
await comboBox.set('searchBucketField', 'extension.raw');
|
||||
await comboBox.set('searchMetricField', 'phpmemory');
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue