-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[UnifiedFieldList] Remove redundant server routes. Create new example…
… plugin for unified field list components and migrate tests. (#158377) - Closes #147885 - Closes #157109 ## Summary **Before:** Unified Field List plugin has internal routes (wrappers for client code) which exist only to run api functional tests against them: - `/api/unified_field_list/existing_fields/{dataViewId}` - `/api/unified_field_list/field_stats` Client code does not call these routes directly. So there is no reason in keeping and versioning them. **After:** - Internal routes are removed - A new "Unified Field List Examples" page was created http://localhost:5601/app/unifiedFieldListExamples - API functional tests (which used the routes) were converted to functional tests against this new example page - Created a new `unifiedFieldList` page object which is used now in functional tests (methods are extracted from existing `discover` page object). **For testing:** Steps: 1. Run Kibana with examples: `yarn start --run-examples` 2. Install sample data 3. And navigate to Developer Examples > Unified Field List Examples page.  ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
- Loading branch information
1 parent
f43096a
commit 8d399fe
Showing
90 changed files
with
2,104 additions
and
1,846 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# unified_field_list_examples | ||
|
||
Examples of unified field list components. | ||
|
||
To run this example, ensure you have data to search against (for example, the sample datasets) and start kibana with the `--run-examples` flag. | ||
|
||
```bash | ||
yarn start --run-examples | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"type": "plugin", | ||
"id": "@kbn/unified-field-list-examples-plugin", | ||
"owner": "@elastic/kibana-data-discovery", | ||
"description": "Examples for using unified field list.", | ||
"plugin": { | ||
"id": "unifiedFieldListExamples", | ||
"server": false, | ||
"browser": true, | ||
"requiredPlugins": [ | ||
"navigation", | ||
"developerExamples", | ||
"inspector", | ||
"kibanaUtils", | ||
"unifiedSearch", | ||
"unifiedFieldList", | ||
"data", | ||
"dataViews", | ||
"dataViewFieldEditor", | ||
"charts", | ||
"fieldFormats" | ||
] | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
examples/unified_field_list_examples/public/application.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { I18nProvider } from '@kbn/i18n-react'; | ||
import type { AppMountParameters, CoreStart } from '@kbn/core/public'; | ||
import { AppPluginStartDependencies } from './types'; | ||
import { UnifiedFieldListExampleApp } from './example_app'; | ||
|
||
export const renderApp = ( | ||
core: CoreStart, | ||
deps: AppPluginStartDependencies, | ||
{ element }: AppMountParameters | ||
) => { | ||
ReactDOM.render( | ||
<I18nProvider> | ||
<UnifiedFieldListExampleApp | ||
services={{ | ||
core, | ||
uiSettings: core.uiSettings, | ||
...deps, | ||
}} | ||
/> | ||
</I18nProvider>, | ||
element | ||
); | ||
|
||
return () => { | ||
ReactDOM.unmountComponentAtNode(element); | ||
}; | ||
}; |
161 changes: 161 additions & 0 deletions
161
examples/unified_field_list_examples/public/example_app.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React, { useCallback, useEffect, useState } from 'react'; | ||
import { css } from '@emotion/react'; | ||
import { | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiPage, | ||
EuiPageBody, | ||
EuiPageSidebar, | ||
EuiTitle, | ||
EuiEmptyPrompt, | ||
EuiLoadingLogo, | ||
} from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
import type { DataView } from '@kbn/data-views-plugin/public'; | ||
import { RootDragDropProvider } from '@kbn/dom-drag-drop'; | ||
import type { DataViewField } from '@kbn/data-views-plugin/public'; | ||
import { PLUGIN_ID, PLUGIN_NAME } from '../common'; | ||
import { FieldListSidebar, FieldListSidebarProps } from './field_list_sidebar'; | ||
import { ExampleDropZone } from './example_drop_zone'; | ||
|
||
interface UnifiedFieldListExampleAppProps { | ||
services: FieldListSidebarProps['services']; | ||
} | ||
|
||
export const UnifiedFieldListExampleApp: React.FC<UnifiedFieldListExampleAppProps> = ({ | ||
services, | ||
}) => { | ||
const { navigation, data, unifiedSearch } = services; | ||
const { IndexPatternSelect } = unifiedSearch.ui; | ||
const [dataView, setDataView] = useState<DataView | null>(); | ||
const [selectedFieldNames, setSelectedFieldNames] = useState<string[]>([]); | ||
|
||
const onAddFieldToWorkplace = useCallback( | ||
(field: DataViewField) => { | ||
setSelectedFieldNames((names) => [...names, field.name]); | ||
}, | ||
[setSelectedFieldNames] | ||
); | ||
|
||
const onRemoveFieldFromWorkspace = useCallback( | ||
(field: DataViewField) => { | ||
setSelectedFieldNames((names) => names.filter((name) => name !== field.name)); | ||
}, | ||
[setSelectedFieldNames] | ||
); | ||
|
||
const onDropFieldToWorkplace = useCallback( | ||
(fieldName: string) => { | ||
setSelectedFieldNames((names) => [...names.filter((name) => name !== fieldName), fieldName]); | ||
}, | ||
[setSelectedFieldNames] | ||
); | ||
|
||
// Fetch the default data view using the `data.dataViews` service, as the component is mounted. | ||
useEffect(() => { | ||
const setDefaultDataView = async () => { | ||
try { | ||
const defaultDataView = await data.dataViews.getDefault(); | ||
setDataView(defaultDataView); | ||
} catch (e) { | ||
setDataView(null); | ||
} | ||
}; | ||
|
||
setDefaultDataView(); | ||
}, [data]); | ||
|
||
if (typeof dataView === 'undefined') { | ||
return ( | ||
<EuiEmptyPrompt | ||
icon={<EuiLoadingLogo logo="logoKibana" size="xl" />} | ||
title={<h2>{PLUGIN_NAME}</h2>} | ||
body={<p>Loading...</p>} | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<EuiPage grow={true}> | ||
<EuiPageBody paddingSize="s"> | ||
<EuiFlexGroup direction="column" gutterSize="xs"> | ||
<EuiFlexItem grow={false}> | ||
<EuiTitle> | ||
<h1>{PLUGIN_NAME}</h1> | ||
</EuiTitle> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<IndexPatternSelect | ||
placeholder={i18n.translate('searchSessionExample.selectDataViewPlaceholder', { | ||
defaultMessage: 'Select data view', | ||
})} | ||
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="dataViewSelector" | ||
/> | ||
</EuiFlexItem> | ||
{dataView ? ( | ||
<> | ||
<EuiFlexItem grow={false}> | ||
<navigation.ui.TopNavMenu | ||
appName={PLUGIN_ID} | ||
showSearchBar={true} | ||
useDefaultBehaviors={true} | ||
indexPatterns={dataView ? [dataView] : undefined} | ||
/> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={true}> | ||
<RootDragDropProvider> | ||
<EuiFlexGroup direction="row" alignItems="stretch"> | ||
<EuiFlexItem grow={false}> | ||
<EuiPageSidebar | ||
css={css` | ||
flex: 1; | ||
width: 320px; | ||
`} | ||
> | ||
<FieldListSidebar | ||
services={services} | ||
dataView={dataView} | ||
selectedFieldNames={selectedFieldNames} | ||
onAddFieldToWorkplace={onAddFieldToWorkplace} | ||
onRemoveFieldFromWorkspace={onRemoveFieldFromWorkspace} | ||
/> | ||
</EuiPageSidebar> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<ExampleDropZone onDropField={onDropFieldToWorkplace} /> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</RootDragDropProvider> | ||
</EuiFlexItem> | ||
</> | ||
) : ( | ||
<EuiEmptyPrompt | ||
iconType="warning" | ||
color="warning" | ||
title={<h2>Select a data view</h2>} | ||
body={<p>Make sure to have at least one data view or install sample data.</p>} | ||
/> | ||
)} | ||
</EuiFlexGroup> | ||
</EuiPageBody> | ||
</EuiPage> | ||
); | ||
}; |
73 changes: 73 additions & 0 deletions
73
examples/unified_field_list_examples/public/example_drop_zone.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React, { useContext, useMemo } from 'react'; | ||
import { DragContext, DragDrop, DropOverlayWrapper, DropType } from '@kbn/dom-drag-drop'; | ||
import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; | ||
|
||
const DROP_PROPS = { | ||
value: { | ||
id: 'exampleDropZone', | ||
humanData: { | ||
label: 'Drop zone for selecting fields', | ||
}, | ||
}, | ||
order: [1, 0, 0, 0], | ||
types: ['field_add'] as DropType[], | ||
}; | ||
|
||
export interface ExampleDropZoneProps { | ||
onDropField: (fieldName: string) => void; | ||
} | ||
|
||
export const ExampleDropZone: React.FC<ExampleDropZoneProps> = ({ onDropField }) => { | ||
const dragDropContext = useContext(DragContext); | ||
const draggingFieldName = dragDropContext.dragging?.id; | ||
|
||
const onDroppingField = useMemo(() => { | ||
if (!draggingFieldName) { | ||
return undefined; | ||
} | ||
|
||
return () => onDropField(draggingFieldName); | ||
}, [onDropField, draggingFieldName]); | ||
|
||
const isDropAllowed = Boolean(onDroppingField); | ||
|
||
return ( | ||
<DragDrop | ||
draggable={false} | ||
dropTypes={isDropAllowed ? DROP_PROPS.types : undefined} | ||
value={DROP_PROPS.value} | ||
order={DROP_PROPS.order} | ||
onDrop={onDroppingField} | ||
> | ||
<DropOverlayWrapper isVisible={isDropAllowed}> | ||
<EuiPanel hasShadow={false} paddingSize="l" className="eui-fullHeight"> | ||
<EuiEmptyPrompt | ||
iconType="beaker" | ||
title={<h3>Example drop zone</h3>} | ||
body={ | ||
<p> | ||
Drop <strong>{draggingFieldName || 'a field'}</strong> here to select it | ||
</p> | ||
} | ||
/> | ||
</EuiPanel> | ||
</DropOverlayWrapper> | ||
</DragDrop> | ||
); | ||
}; |
Oops, something went wrong.