kibana/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx
2020-09-29 19:00:29 +02:00

115 lines
4 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import './data_panel_wrapper.scss';
import React, { useMemo, memo, useContext, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiPopover, EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui';
import { NativeRenderer } from '../../native_renderer';
import { Action } from './state_management';
import { DragContext } from '../../drag_drop';
import { StateSetter, FramePublicAPI, DatasourceDataPanelProps, Datasource } from '../../types';
import { Query, Filter } from '../../../../../../src/plugins/data/public';
interface DataPanelWrapperProps {
datasourceState: unknown;
datasourceMap: Record<string, Datasource>;
activeDatasource: string | null;
datasourceIsLoading: boolean;
dispatch: (action: Action) => void;
showNoDataPopover: () => void;
core: DatasourceDataPanelProps['core'];
query: Query;
dateRange: FramePublicAPI['dateRange'];
filters: Filter[];
}
export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => {
const { dispatch, activeDatasource } = props;
const setDatasourceState: StateSetter<unknown> = useMemo(
() => (updater) => {
dispatch({
type: 'UPDATE_DATASOURCE_STATE',
updater,
datasourceId: activeDatasource!,
clearStagedPreview: true,
});
},
[dispatch, activeDatasource]
);
const datasourceProps: DatasourceDataPanelProps = {
dragDropContext: useContext(DragContext),
state: props.datasourceState,
setState: setDatasourceState,
core: props.core,
query: props.query,
dateRange: props.dateRange,
filters: props.filters,
showNoDataPopover: props.showNoDataPopover,
};
const [showDatasourceSwitcher, setDatasourceSwitcher] = useState(false);
return (
<>
{Object.keys(props.datasourceMap).length > 1 && (
<EuiPopover
id="datasource-switch"
className="lnsDataPanelWrapper__switchSource"
button={
<EuiButtonIcon
aria-label={i18n.translate('xpack.lens.dataPanelWrapper.switchDatasource', {
defaultMessage: 'Switch to datasource',
})}
title={i18n.translate('xpack.lens.dataPanelWrapper.switchDatasource', {
defaultMessage: 'Switch to datasource',
})}
data-test-subj="datasource-switch"
onClick={() => setDatasourceSwitcher(true)}
iconType="gear"
/>
}
isOpen={showDatasourceSwitcher}
closePopover={() => setDatasourceSwitcher(false)}
panelPaddingSize="none"
anchorPosition="rightUp"
>
<EuiContextMenuPanel
title={i18n.translate('xpack.lens.dataPanelWrapper.switchDatasource', {
defaultMessage: 'Switch to datasource',
})}
items={Object.keys(props.datasourceMap).map((datasourceId) => (
<EuiContextMenuItem
key={datasourceId}
data-test-subj={`datasource-switch-${datasourceId}`}
icon={props.activeDatasource === datasourceId ? 'check' : 'empty'}
onClick={() => {
setDatasourceSwitcher(false);
props.dispatch({
type: 'SWITCH_DATASOURCE',
newDatasourceId: datasourceId,
});
}}
>
{datasourceId}
</EuiContextMenuItem>
))}
/>
</EuiPopover>
)}
{props.activeDatasource && !props.datasourceIsLoading && (
<NativeRenderer
className="lnsDataPanelWrapper"
render={props.datasourceMap[props.activeDatasource].renderDataPanel}
nativeProps={datasourceProps}
/>
)}
</>
);
});