Skip to content

Commit

Permalink
[Canvas][tech-debt] Update Redux components to reflect new structure (e…
Browse files Browse the repository at this point in the history
…lastic#73844) (elastic#73967)

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
clintandrewhall and elasticmachine committed Jul 31, 2020
1 parent b8f2749 commit 5b4e79f
Show file tree
Hide file tree
Showing 56 changed files with 1,466 additions and 1,345 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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 React, { FC } from 'react';
import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui';
import {
SavedObjectFinderUi,
SavedObjectMetaData,
} from '../../../../../../src/plugins/saved_objects/public/';
import { ComponentStrings } from '../../../i18n';
import { useServices } from '../../services';

const { AddEmbeddableFlyout: strings } = ComponentStrings;

export interface Props {
onClose: () => void;
onSelect: (id: string, embeddableType: string) => void;
availableEmbeddables: string[];
}

export const AddEmbeddableFlyout: FC<Props> = ({ onSelect, availableEmbeddables, onClose }) => {
const services = useServices();
const { embeddables, platform } = services;
const { getEmbeddableFactories } = embeddables;
const { getSavedObjects, getUISettings } = platform;

const onAddPanel = (id: string, savedObjectType: string, name: string) => {
const embeddableFactories = getEmbeddableFactories();

// Find the embeddable type from the saved object type
const found = Array.from(embeddableFactories).find((embeddableFactory) => {
return Boolean(
embeddableFactory.savedObjectMetaData &&
embeddableFactory.savedObjectMetaData.type === savedObjectType
);
});

const foundEmbeddableType = found ? found.type : 'unknown';

onSelect(id, foundEmbeddableType);
};

const embeddableFactories = getEmbeddableFactories();

const availableSavedObjects = Array.from(embeddableFactories)
.filter((factory) => {
return availableEmbeddables.includes(factory.type);
})
.map((factory) => factory.savedObjectMetaData)
.filter<SavedObjectMetaData<{}>>(function (
maybeSavedObjectMetaData
): maybeSavedObjectMetaData is SavedObjectMetaData<{}> {
return maybeSavedObjectMetaData !== undefined;
});

return (
<EuiFlyout ownFocus onClose={onClose} data-test-subj="dashboardAddPanel">
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>{strings.getTitleText()}</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<SavedObjectFinderUi
onChoose={onAddPanel}
savedObjectMetaData={availableSavedObjects}
showFilter={true}
noItemsMessage={strings.getNoItemsText()}
savedObjects={getSavedObjects()}
uiSettings={getUISettings()}
/>
</EuiFlyoutBody>
</EuiFlyout>
);
};
160 changes: 96 additions & 64 deletions x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,107 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { FC } from 'react';
import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui';
import {
SavedObjectFinderUi,
SavedObjectMetaData,
} from '../../../../../../src/plugins/saved_objects/public/';
import { ComponentStrings } from '../../../i18n';
import { useServices } from '../../services';

const { AddEmbeddableFlyout: strings } = ComponentStrings;

export interface Props {
onClose: () => void;
onSelect: (id: string, embeddableType: string) => void;
availableEmbeddables: string[];
import React from 'react';
import ReactDOM from 'react-dom';
import { compose } from 'recompose';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { AddEmbeddableFlyout as Component, Props as ComponentProps } from './flyout.component';
// @ts-expect-error untyped local
import { addElement } from '../../state/actions/elements';
import { getSelectedPage } from '../../state/selectors/workpad';
import { EmbeddableTypes } from '../../../canvas_plugin_src/expression_types/embeddable';

const allowedEmbeddables = {
[EmbeddableTypes.map]: (id: string) => {
return `savedMap id="${id}" | render`;
},
[EmbeddableTypes.lens]: (id: string) => {
return `savedLens id="${id}" | render`;
},
[EmbeddableTypes.visualization]: (id: string) => {
return `savedVisualization id="${id}" | render`;
},
/*
[EmbeddableTypes.search]: (id: string) => {
return `filters | savedSearch id="${id}" | render`;
},*/
};

interface StateProps {
pageId: string;
}

interface DispatchProps {
addEmbeddable: (pageId: string, partialElement: { expression: string }) => void;
}

export const AddEmbeddableFlyout: FC<Props> = ({ onSelect, availableEmbeddables, onClose }) => {
const services = useServices();
const { embeddables, platform } = services;
const { getEmbeddableFactories } = embeddables;
const { getSavedObjects, getUISettings } = platform;
// FIX: Missing state type
const mapStateToProps = (state: any) => ({ pageId: getSelectedPage(state) });

const onAddPanel = (id: string, savedObjectType: string, name: string) => {
const embeddableFactories = getEmbeddableFactories();
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
addEmbeddable: (pageId, partialElement): DispatchProps['addEmbeddable'] =>
dispatch(addElement(pageId, partialElement)),
});

// Find the embeddable type from the saved object type
const found = Array.from(embeddableFactories).find((embeddableFactory) => {
return Boolean(
embeddableFactory.savedObjectMetaData &&
embeddableFactory.savedObjectMetaData.type === savedObjectType
);
});
const mergeProps = (
stateProps: StateProps,
dispatchProps: DispatchProps,
ownProps: ComponentProps
): ComponentProps => {
const { pageId, ...remainingStateProps } = stateProps;
const { addEmbeddable } = dispatchProps;

const foundEmbeddableType = found ? found.type : 'unknown';
return {
...remainingStateProps,
...ownProps,
onSelect: (id: string, type: string): void => {
const partialElement = {
expression: `markdown "Could not find embeddable for type ${type}" | render`,
};
if (allowedEmbeddables[type]) {
partialElement.expression = allowedEmbeddables[type](id);
}

onSelect(id, foundEmbeddableType);
addEmbeddable(pageId, partialElement);
ownProps.onClose();
},
};

const embeddableFactories = getEmbeddableFactories();

const availableSavedObjects = Array.from(embeddableFactories)
.filter((factory) => {
return availableEmbeddables.includes(factory.type);
})
.map((factory) => factory.savedObjectMetaData)
.filter<SavedObjectMetaData<{}>>(function (
maybeSavedObjectMetaData
): maybeSavedObjectMetaData is SavedObjectMetaData<{}> {
return maybeSavedObjectMetaData !== undefined;
});

return (
<EuiFlyout ownFocus onClose={onClose} data-test-subj="dashboardAddPanel">
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>{strings.getTitleText()}</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<SavedObjectFinderUi
onChoose={onAddPanel}
savedObjectMetaData={availableSavedObjects}
showFilter={true}
noItemsMessage={strings.getNoItemsText()}
savedObjects={getSavedObjects()}
uiSettings={getUISettings()}
/>
</EuiFlyoutBody>
</EuiFlyout>
);
};

export class EmbeddableFlyoutPortal extends React.Component<ComponentProps> {
el?: HTMLElement;

constructor(props: ComponentProps) {
super(props);

this.el = document.createElement('div');
}
componentDidMount() {
const body = document.querySelector('body');
if (body && this.el) {
body.appendChild(this.el);
}
}

componentWillUnmount() {
const body = document.querySelector('body');

if (body && this.el) {
body.removeChild(this.el);
}
}

render() {
if (this.el) {
return ReactDOM.createPortal(
<Component {...this.props} availableEmbeddables={Object.keys(allowedEmbeddables)} />,
this.el
);
}
}
}

export const AddEmbeddablePanel = compose<ComponentProps, { onClose: () => void }>(
connect(mapStateToProps, mapDispatchToProps, mergeProps)
)(EmbeddableFlyoutPortal);
11 changes: 11 additions & 0 deletions x-pack/plugins/canvas/public/components/embeddable_flyout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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.
*/

export { EmbeddableFlyoutPortal, AddEmbeddablePanel } from './flyout';
export {
AddEmbeddableFlyout as AddEmbeddableFlyoutComponent,
Props as AddEmbeddableFlyoutComponentProps,
} from './flyout.component';
113 changes: 0 additions & 113 deletions x-pack/plugins/canvas/public/components/embeddable_flyout/index.tsx

This file was deleted.

Loading

0 comments on commit 5b4e79f

Please sign in to comment.