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

[Lens] visualize in maps button #98677

Merged
merged 28 commits into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ebded20
[Lens] visualize in maps button
nreese Apr 28, 2021
ae91101
Merge branch 'master' into lens_link_to_maps
kibanamachine Apr 29, 2021
8762935
clean up dependency injection as suggested
nreese Apr 29, 2021
a707d1b
add custom workspace render for geo fields
nreese Apr 30, 2021
c97fa4b
Merge branch 'master' into lens_link_to_maps
kibanamachine May 3, 2021
1ebfdea
tslint and finish drag and drop for geo field
nreese May 3, 2021
c4fc65c
convert react class to function component
nreese May 3, 2021
76313c5
prevent page reload when clicking visualize in maps button
nreese May 3, 2021
dab538d
filter allFields instead of using condition to populate fieldTypeName…
nreese May 4, 2021
9dd3d02
clean up UI
nreese May 4, 2021
5702835
fix jest test
nreese May 4, 2021
a59bef7
globe illustration
nreese May 4, 2021
c4f9207
Merge branch 'master' into lens_link_to_maps
kibanamachine May 5, 2021
68a3b54
UI cleanup
nreese May 5, 2021
1ecc000
functional test
nreese May 5, 2021
873294c
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
21d16a6
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
5fffe4b
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
05f6b5d
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
db3ba29
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
ae91b07
Update x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx
nreese May 10, 2021
e2f1b3d
Merge branch 'master' into lens_link_to_maps
kibanamachine May 10, 2021
050080b
updated globe svg
nreese May 10, 2021
e5a118a
remove unused
nreese May 10, 2021
6c50c4e
better message for drop zone screen reader
nreese May 10, 2021
73b4549
Update x-pack/plugins/lens/public/editor_frame_service/editor_frame/w…
nreese May 10, 2021
2eb13d5
tslint
nreese May 10, 2021
b6af7e4
Merge branch 'master' into lens_link_to_maps
kibanamachine May 12, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Action } from './state_management';
import { DragContext, DragDropIdentifier } from '../../drag_drop';
import { StateSetter, FramePublicAPI, DatasourceDataPanelProps, Datasource } from '../../types';
import { Query, Filter } from '../../../../../../src/plugins/data/public';
import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public';

interface DataPanelWrapperProps {
datasourceState: unknown;
Expand All @@ -29,6 +30,7 @@ interface DataPanelWrapperProps {
filters: Filter[];
dropOntoWorkspace: (field: DragDropIdentifier) => void;
hasSuggestionForField: (field: DragDropIdentifier) => boolean;
plugins: { uiActions: UiActionsStart };
}

export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => {
Expand Down Expand Up @@ -56,6 +58,7 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => {
showNoDataPopover: props.showNoDataPopover,
dropOntoWorkspace: props.dropOntoWorkspace,
hasSuggestionForField: props.hasSuggestionForField,
uiActions: props.plugins.uiActions,
};

const [showDatasourceSwitcher, setDatasourceSwitcher] = useState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ export function EditorFrame(props: EditorFrameProps) {
showNoDataPopover={props.showNoDataPopover}
dropOntoWorkspace={dropOntoWorkspace}
hasSuggestionForField={hasSuggestionForField}
plugins={props.plugins}
/>
}
configPanel={
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@import '../../../mixins';

.lnsVisualizeGeoFieldWorkspacePanel__dragDrop {
width: $euiSizeXXL * 8;
height: $euiSizeXXL;
border: $euiBorderThin;
border-radius: $euiBorderRadiusSmall;

&.lnsDragDrop-isDropTarget {
@include lnsDroppable;
@include lnsDroppableActive;

p {
transition: filter $euiAnimSpeedFast ease-in-out;
filter: blur(5px);
}

.lnsExpressionRenderer {
transition: filter $euiAnimSpeedNormal ease-in-out, opacity $euiAnimSpeedNormal ease-in-out;
filter: blur($euiSizeXS);
opacity: .25;
}
}

&.lnsDragDrop-isActiveDropTarget {
@include lnsDroppableActiveHover;

.lnsDropIllustration__hand {
animation: lnsWorkspacePanel__illustrationPulseContinuous 1.5s ease-in-out 0s infinite normal forwards;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import {
UiActionsStart,
VISUALIZE_GEO_FIELD_TRIGGER,
} from '../../../../../../../src/plugins/ui_actions/public';
import { getVisualizeGeoFieldMessage } from '../../../utils';
import { DragDrop } from '../../../drag_drop';
import './geo_field_workspace_panel.scss';

interface Props {
fieldType: string;
fieldName: string;
indexPatternId: string;
uiActions: UiActionsStart;
}

const dragDropIdentifier = {
id: 'lnsGeoFieldWorkspace',
humanData: {
label: i18n.translate('xpack.lens.geoFieldWorkspace.workspaceLabel', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to construct the screen reader message if the user picks up the field using keyboard and moves it to the drop zone:
Screenshot 2021-05-06 at 15 51 38

We can either add a special case for this here (extending humanData for a special message):

: i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.defaultNoPosition', {

or think about something that fits into the existing template and makes clear this will move the user to Maps.

defaultMessage: 'Geo field workspace',
}),
},
};

const dragDropOrder = [1, 0, 0, 0];

export function GeoFieldWorkspacePanel(props: Props) {
function onDrop() {
props.uiActions.getTrigger(VISUALIZE_GEO_FIELD_TRIGGER).exec({
indexPatternId: props.indexPatternId,
fieldName: props.fieldName,
});
}

return (
<EuiText
className="lnsWorkspacePanel__emptyContent"
textAlign="center"
color="subdued"
size="s"
>
<h2>
<strong>{getVisualizeGeoFieldMessage(props.fieldType)}</strong>
</h2>
<DragDrop
className="lnsVisualizeGeoFieldWorkspacePanel__dragDrop"
dataTestSubj="lnsGeoFieldWorkspace"
draggable={false}
dropTypes={['field_add']}
order={dragDropOrder}
value={dragDropIdentifier}
onDrop={onDrop}
>
<div>
<FormattedMessage
id="xpack.lens.geoFieldWorkspace.dropMessage"
defaultMessage="Drop field here to open in Maps"
/>
</div>
</DragDrop>
</EuiText>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,22 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
);
};

return (
<WorkspacePanelWrapper
title={title}
framePublicAPI={framePublicAPI}
dispatch={dispatch}
visualizationState={visualizationState}
visualizationId={activeVisualizationId}
datasourceStates={datasourceStates}
datasourceMap={datasourceMap}
visualizationMap={visualizationMap}
>
const dragDropContext = useContext(DragContext);

const renderDragDrop = () => {
const customWorkspaceRenderer =
activeDatasourceId &&
datasourceMap[activeDatasourceId].getCustomWorkspaceRenderer &&
dragDropContext.dragging
? datasourceMap[activeDatasourceId].getCustomWorkspaceRenderer!(
datasourceStates[activeDatasourceId].state,
dragDropContext.dragging
)
: undefined;

return customWorkspaceRenderer ? (
customWorkspaceRenderer()
) : (
<DragDrop
className="lnsWorkspacePanel__dragDrop"
dataTestSubj="lnsWorkspace"
Expand All @@ -363,6 +368,21 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
{Boolean(suggestionForDraggedField) && expression !== null && renderEmptyWorkspace()}
</EuiPageContentBody>
</DragDrop>
);
};

return (
<WorkspacePanelWrapper
title={title}
framePublicAPI={framePublicAPI}
dispatch={dispatch}
visualizationState={visualizationState}
visualizationId={activeVisualizationId}
datasourceStates={datasourceStates}
datasourceMap={datasourceMap}
visualizationMap={visualizationMap}
>
{renderDragDrop()}
</WorkspacePanelWrapper>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export interface EditorFrameStartPlugins {
embeddable?: EmbeddableStart;
dashboard?: DashboardStart;
expressions: ExpressionsStart;
uiActions?: UiActionsStart;
uiActions: UiActionsStart;
charts: ChartsPluginSetup;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { documentField } from './document_field';
import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks';
import { indexPatternFieldEditorPluginMock } from '../../../../../src/plugins/index_pattern_field_editor/public/mocks';
import { getFieldByNameFactory } from './pure_helpers';
import { uiActionsPluginMock } from '../../../../../src/plugins/ui_actions/public/mocks';

const fieldsOne = [
{
Expand Down Expand Up @@ -267,6 +268,7 @@ describe('IndexPattern Data Panel', () => {
showNoDataPopover: jest.fn(),
dropOntoWorkspace: jest.fn(),
hasSuggestionForField: jest.fn(() => false),
uiActions: uiActionsPluginMock.createStartContract(),
};
});

Expand Down
66 changes: 43 additions & 23 deletions x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { fieldExists } from './pure_helpers';
import { Loader } from '../loader';
import { esQuery, IIndexPattern } from '../../../../../src/plugins/data/public';
import { IndexPatternFieldEditorStart } from '../../../../../src/plugins/index_pattern_field_editor/public';
import { VISUALIZE_GEO_FIELD_TRIGGER } from '../../../../../src/plugins/ui_actions/public';

export type Props = Omit<DatasourceDataPanelProps<IndexPatternPrivateState>, 'core'> & {
data: DataPublicPluginStart;
Expand All @@ -62,29 +63,6 @@ function sortFields(fieldA: IndexPatternField, fieldB: IndexPatternField) {
return fieldA.displayName.localeCompare(fieldB.displayName, undefined, { sensitivity: 'base' });
}

const supportedFieldTypes = new Set([
'string',
'number',
'boolean',
'date',
'ip',
'number_range',
'date_range',
'ip_range',
'histogram',
'document',
]);

const fieldTypeNames: Record<DataType, string> = {
document: i18n.translate('xpack.lens.datatypes.record', { defaultMessage: 'record' }),
string: i18n.translate('xpack.lens.datatypes.string', { defaultMessage: 'string' }),
number: i18n.translate('xpack.lens.datatypes.number', { defaultMessage: 'number' }),
boolean: i18n.translate('xpack.lens.datatypes.boolean', { defaultMessage: 'boolean' }),
date: i18n.translate('xpack.lens.datatypes.date', { defaultMessage: 'date' }),
ip: i18n.translate('xpack.lens.datatypes.ipAddress', { defaultMessage: 'IP' }),
histogram: i18n.translate('xpack.lens.datatypes.histogram', { defaultMessage: 'histogram' }),
};

// Wrapper around esQuery.buildEsQuery, handling errors (e.g. because a query can't be parsed) by
// returning a query dsl object not matching anything
function buildSafeEsQuery(
Expand Down Expand Up @@ -121,6 +99,7 @@ export function IndexPatternDataPanel({
showNoDataPopover,
dropOntoWorkspace,
hasSuggestionForField,
uiActions,
}: Props) {
const { indexPatternRefs, indexPatterns, currentIndexPatternId } = state;
const onChangeIndexPattern = useCallback(
Expand Down Expand Up @@ -233,6 +212,7 @@ export function IndexPatternDataPanel({
existenceFetchTimeout={state.existenceFetchTimeout}
dropOntoWorkspace={dropOntoWorkspace}
hasSuggestionForField={hasSuggestionForField}
uiActions={uiActions}
/>
)}
</>
Expand Down Expand Up @@ -286,6 +266,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
charts,
dropOntoWorkspace,
hasSuggestionForField,
uiActions,
}: Omit<DatasourceDataPanelProps, 'state' | 'setState' | 'showNoDataPopover' | 'core'> & {
data: DataPublicPluginStart;
core: CoreStart;
Expand All @@ -309,6 +290,26 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
isEmptyAccordionOpen: false,
isMetaAccordionOpen: false,
});

const fieldTypeNames: Record<DataType, string> = {
document: i18n.translate('xpack.lens.datatypes.record', { defaultMessage: 'record' }),
string: i18n.translate('xpack.lens.datatypes.string', { defaultMessage: 'string' }),
number: i18n.translate('xpack.lens.datatypes.number', { defaultMessage: 'number' }),
boolean: i18n.translate('xpack.lens.datatypes.boolean', { defaultMessage: 'boolean' }),
date: i18n.translate('xpack.lens.datatypes.date', { defaultMessage: 'date' }),
ip: i18n.translate('xpack.lens.datatypes.ipAddress', { defaultMessage: 'IP' }),
histogram: i18n.translate('xpack.lens.datatypes.histogram', { defaultMessage: 'histogram' }),
};
const visualizeGeoFieldTrigger = uiActions.getTrigger(VISUALIZE_GEO_FIELD_TRIGGER);
if (visualizeGeoFieldTrigger) {
fieldTypeNames.geo_point = i18n.translate('xpack.lens.datatypes.geoPoint', {
defaultMessage: 'geo_point',
});
fieldTypeNames.geo_shape = i18n.translate('xpack.lens.datatypes.geoShape', {
defaultMessage: 'geo_shape',
});
}

const currentIndexPattern = indexPatterns[currentIndexPatternId];
const allFields = currentIndexPattern.fields;
const clearLocalState = () => setLocalState((s) => ({ ...s, nameFilter: '', typeFilter: [] }));
Expand All @@ -323,6 +324,23 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
const editPermission = indexPatternFieldEditor.userPermissions.editIndexPattern();

const unfilteredFieldGroups: FieldGroups = useMemo(() => {
const supportedFieldTypes = new Set([
'string',
'number',
'boolean',
'date',
'ip',
'number_range',
'date_range',
'ip_range',
'histogram',
'document',
]);
if (visualizeGeoFieldTrigger) {
supportedFieldTypes.add('geo_point');
supportedFieldTypes.add('geo_shape');
}

const containsData = (field: IndexPatternField) => {
const overallField = currentIndexPattern.getFieldByName(field.name);

Expand Down Expand Up @@ -449,6 +467,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
existenceFetchTimeout,
currentIndexPattern,
existingFields,
visualizeGeoFieldTrigger,
]);

const fieldGroups: FieldGroups = useMemo(() => {
Expand Down Expand Up @@ -807,6 +826,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
hasSuggestionForField={hasSuggestionForField}
editField={editField}
removeField={removeField}
uiActions={uiActions}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks';
import { IndexPattern } from './types';
import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks';
import { documentField } from './document_field';
import { uiActionsPluginMock } from '../../../../../src/plugins/ui_actions/public/mocks';

const chartsThemeService = chartPluginMock.createSetupContract().theme;

Expand Down Expand Up @@ -109,6 +110,7 @@ describe('IndexPattern Field Item', () => {
itemIndex: 0,
dropOntoWorkspace: () => {},
hasSuggestionForField: () => false,
uiActions: uiActionsPluginMock.createStartContract(),
};

data.fieldFormats = ({
Expand Down
Loading