Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UnifiedFieldList] Remove redundant server routes. Create new example plugin for unified field list components and migrate tests. #158377

Merged
merged 31 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2a92ef1
[UnifiedFieldList] Create new example plugin for unified field list c…
jughosta May 24, 2023
94db4af
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 24, 2023
03fafa4
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine May 24, 2023
2e69ec2
[UnifiedFieldList] Extend the example
jughosta May 24, 2023
b2df82a
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 24, 2023
8ab8123
[UnifiedFieldList] Update actions
jughosta May 24, 2023
04cb3dc
[UnifiedFieldList] Fix types
jughosta May 24, 2023
6da8214
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 24, 2023
1f76b03
[UnifiedFieldList] Add a drop zone
jughosta May 24, 2023
45fe68f
Merge remote-tracking branch 'origin/157109-remove-server-routes' int…
jughosta May 24, 2023
5f3910a
[UnifiedFieldList] Add new page object
jughosta May 25, 2023
5c74340
[UnifiedFieldList] Fix tests
jughosta May 25, 2023
4270689
[UnifiedFieldList] Update more tests
jughosta May 25, 2023
5e07ed3
[UnifiedFieldList] Update more tests
jughosta May 25, 2023
1dbfe09
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine May 25, 2023
7b2720d
[UnifiedFieldList] Update field existence tests
jughosta May 25, 2023
363a101
Merge remote-tracking branch 'origin/157109-remove-server-routes' int…
jughosta May 25, 2023
d85cf13
[UnifiedFieldList] Remove redundant code
jughosta May 25, 2023
e68299b
[UnifiedFieldList] Rearrange the code
jughosta May 25, 2023
27f82f3
[UnifiedFieldList] Revert some changes for later
jughosta May 26, 2023
70a3a15
Merge remote-tracking branch 'upstream/main' into 157109-remove-serve…
jughosta May 26, 2023
8353c72
[UnifiedFieldList] Add a comment
jughosta May 26, 2023
50b2bd5
[UnifiedFieldList] Add a preview image
jughosta May 26, 2023
0903ac8
Merge branch 'main' into 157109-remove-server-routes
jughosta May 26, 2023
3970974
[UnifiedFieldList] Switch to div
jughosta May 26, 2023
be5f421
Merge branch 'main' into 157109-remove-server-routes
jughosta May 28, 2023
f833612
Merge branch 'main' into 157109-remove-server-routes
jughosta May 29, 2023
1192c40
[UnifiedFieldList] Use plugin id
jughosta May 30, 2023
284a101
Merge branch 'main' into 157109-remove-server-routes
jughosta May 31, 2023
a10f893
[UnifiedFieldList] Update tests
jughosta May 31, 2023
0fb831e
Merge branch 'main' into 157109-remove-server-routes
jughosta May 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ test/plugin_functional/plugins/ui_settings_plugin @elastic/kibana-core
packages/kbn-ui-shared-deps-npm @elastic/kibana-operations
packages/kbn-ui-shared-deps-src @elastic/kibana-operations
packages/kbn-ui-theme @elastic/kibana-operations
examples/unified_field_list_examples @elastic/kibana-data-discovery
src/plugins/unified_field_list @elastic/kibana-data-discovery
src/plugins/unified_histogram @elastic/kibana-data-discovery
src/plugins/unified_search @elastic/kibana-visualizations
Expand Down
9 changes: 9 additions & 0 deletions examples/unified_field_list_examples/README.md
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
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
* Side Public License, v 1.
*/

export const BASE_API_PATH = '/internal/unified_field_list';
export const FIELD_STATS_API_PATH = `${BASE_API_PATH}/field_stats`;
export const FIELD_EXISTING_API_PATH = `${BASE_API_PATH}/existing_fields/{dataViewId}`;
export const PLUGIN_ID = 'unifiedFieldListExamples';
export const PLUGIN_NAME = 'UnifiedFieldList Examples';
24 changes: 24 additions & 0 deletions examples/unified_field_list_examples/kibana.jsonc
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 examples/unified_field_list_examples/public/application.tsx
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 examples/unified_field_list_examples/public/example_app.tsx
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>
);
};
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>
);
};
Loading