Skip to content

Commit

Permalink
make create instance async and move registration into separate services
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 committed Feb 7, 2020
1 parent 07d101e commit b18f96f
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@ import { datatableVisualization } from './visualization';
import { ExpressionsSetup } from '../../../../../../src/plugins/expressions/public';
import { datatable, datatableColumns, getDatatableRenderer } from './expression';
import { FormatFactory } from '../legacy_imports';
import { EditorFrameSetup } from '../types';

export interface DatatableVisualizationPluginSetupPlugins {
expressions: ExpressionsSetup;
formatFactory: FormatFactory;
editorFrame: EditorFrameSetup;
}

export class DatatableVisualization {
constructor() {}

setup(
_core: CoreSetup | null,
{ expressions, formatFactory }: DatatableVisualizationPluginSetupPlugins
{ expressions, formatFactory, editorFrame }: DatatableVisualizationPluginSetupPlugins
) {
expressions.registerFunction(() => datatableColumns);
expressions.registerFunction(() => datatable);
expressions.registerRenderer(() => getDatatableRenderer(formatFactory));

return datatableVisualization;
editorFrame.registerVisualization(datatableVisualization);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,28 @@ describe('editor_frame service', () => {
mountpoint.remove();
});

it('should create an editor frame instance which mounts and unmounts', () => {
expect(() => {
pluginInstance.setup(coreMock.createSetup(), pluginSetupDependencies);
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
const instance = publicAPI.createInstance({});
instance.mount(mountpoint, {
onError: jest.fn(),
onChange: jest.fn(),
dateRange: { fromDate: '', toDate: '' },
query: { query: '', language: 'lucene' },
filters: [],
});
instance.unmount();
}).not.toThrowError();
it('should create an editor frame instance which mounts and unmounts', async () => {
await expect(
(async () => {
pluginInstance.setup(coreMock.createSetup(), pluginSetupDependencies);
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
const instance = await publicAPI.createInstance({});
instance.mount(mountpoint, {
onError: jest.fn(),
onChange: jest.fn(),
dateRange: { fromDate: '', toDate: '' },
query: { query: '', language: 'lucene' },
filters: [],
});
instance.unmount();
})()
).resolves.toBeUndefined();
});

it('should not have child nodes after unmount', () => {
it('should not have child nodes after unmount', async () => {
pluginInstance.setup(coreMock.createSetup(), pluginSetupDependencies);
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
const instance = publicAPI.createInstance({});
const instance = await publicAPI.createInstance({});
instance.mount(mountpoint, {
onError: jest.fn(),
onChange: jest.fn(),
Expand Down
39 changes: 30 additions & 9 deletions x-pack/legacy/plugins/lens/public/editor_frame_service/service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,37 @@ export interface EditorFrameStartPlugins {
expressions: ExpressionsStart;
}

async function collectAsyncDefinitions<T extends { id: string }>(
definitions: Array<T | Promise<T>>
) {
const resolvedDefinitions = await Promise.all(
definitions.map(definition =>
definition instanceof Promise ? definition : Promise.resolve(definition)
)
);
const definitionMap: Record<string, T> = {};
resolvedDefinitions.forEach(definition => {
definitionMap[definition.id] = definition;
});

return definitionMap;
}

export class EditorFrameService {
constructor() {}

private readonly datasources: Record<string, Datasource> = {};
private readonly visualizations: Record<string, Visualization> = {};
private readonly datasources: Array<Datasource | Promise<Datasource>> = [];
private readonly visualizations: Array<Visualization | Promise<Visualization>> = [];

public setup(core: CoreSetup, plugins: EditorFrameSetupPlugins): EditorFrameSetup {
plugins.expressions.registerFunction(() => mergeTables);

return {
registerDatasource: datasource => {
this.datasources[datasource.id] = datasource as Datasource<unknown, unknown>;
this.datasources.push(datasource as Datasource<unknown, unknown>);
},
registerVisualization: visualization => {
this.visualizations[visualization.id] = visualization as Visualization<unknown, unknown>;
this.visualizations.push(visualization as Visualization<unknown, unknown>);
},
};
}
Expand All @@ -75,21 +91,26 @@ export class EditorFrameService {
)
);

const createInstance = (): EditorFrameInstance => {
const createInstance = async (): Promise<EditorFrameInstance> => {
let domElement: Element;
const [resolvedDatasources, resolvedVisualizations] = await Promise.all([
collectAsyncDefinitions(this.datasources),
collectAsyncDefinitions(this.visualizations),
]);

return {
mount: (element, { doc, onError, dateRange, query, filters, savedQuery, onChange }) => {
domElement = element;
const firstDatasourceId = Object.keys(this.datasources)[0];
const firstVisualizationId = Object.keys(this.visualizations)[0];
const firstDatasourceId = Object.keys(resolvedDatasources)[0];
const firstVisualizationId = Object.keys(resolvedVisualizations)[0];

render(
<I18nProvider>
<EditorFrame
data-test-subj="lnsEditorFrame"
onError={onError}
datasourceMap={this.datasources}
visualizationMap={this.visualizations}
datasourceMap={resolvedDatasources}
visualizationMap={resolvedVisualizations}
initialDatasourceId={getActiveDatasourceIdFromDoc(doc) || firstDatasourceId || null}
initialVisualizationId={
(doc && doc.visualizationType) || firstVisualizationId || null
Expand Down
19 changes: 12 additions & 7 deletions x-pack/legacy/plugins/lens/public/indexpattern_datasource/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import {
DataPublicPluginSetup,
DataPublicPluginStart,
} from '../../../../../../src/plugins/data/public';
import { Datasource, EditorFrameSetup } from '../types';

export interface IndexPatternDatasourceSetupPlugins {
expressions: ExpressionsSetup;
data: DataPublicPluginSetup;
editorFrame: EditorFrameSetup;
}

export interface IndexPatternDatasourceStartPlugins {
Expand All @@ -29,16 +31,19 @@ export class IndexPatternDatasource {

setup(
core: CoreSetup<IndexPatternDatasourceStartPlugins>,
{ expressions }: IndexPatternDatasourceSetupPlugins
{ expressions, editorFrame }: IndexPatternDatasourceSetupPlugins
) {
expressions.registerFunction(renameColumns);
expressions.registerFunction(autoDate);

return getIndexPatternDatasource({
core,
storage: new Storage(localStorage),
savedObjectsClient: core.getStartServices().then(([{ savedObjects }]) => savedObjects.client),
data: core.getStartServices().then(([_, { data }]) => data),
});
editorFrame.registerDatasource(
core.getStartServices().then(([coreStart, { data }]) =>
getIndexPatternDatasource({
core: coreStart,
storage: new Storage(localStorage),
data,
})
) as Promise<Datasource>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { SavedObjectsClientContract } from 'kibana/public';
import { getIndexPatternDatasource, IndexPatternColumn, uniqueLabels } from './indexpattern';
import { DatasourcePublicAPI, Operation, Datasource } from '../types';
import { coreMock } from 'src/core/public/mocks';
Expand Down Expand Up @@ -140,9 +139,8 @@ describe('IndexPattern Data Source', () => {
beforeEach(() => {
indexPatternDatasource = getIndexPatternDatasource({
storage: {} as IStorageWrapper,
core: coreMock.createSetup(),
savedObjectsClient: Promise.resolve({} as SavedObjectsClientContract),
data: Promise.resolve(pluginsMock.createStart().data),
core: coreMock.createStart(),
data: pluginsMock.createStart().data,
});

persistedState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import _ from 'lodash';
import React from 'react';
import { render } from 'react-dom';
import { I18nProvider } from '@kbn/i18n/react';
import { CoreSetup, SavedObjectsClientContract } from 'src/core/public';
import { CoreStart } from 'src/core/public';
import { i18n } from '@kbn/i18n';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import {
Expand Down Expand Up @@ -91,16 +91,13 @@ export function uniqueLabels(layers: Record<string, IndexPatternLayer>) {
export function getIndexPatternDatasource({
core,
storage,
savedObjectsClient,
data,
}: {
// Core start is being required here because it contains the savedObject client
// In the new platform, this plugin wouldn't be initialized until after setup
core: CoreSetup;
core: CoreStart;
storage: IStorageWrapper;
savedObjectsClient: Promise<SavedObjectsClientContract>;
data: Promise<ReturnType<DataPlugin['start']>>;
data: ReturnType<DataPlugin['start']>;
}) {
const savedObjectsClient = core.savedObjects.client;
const uiSettings = core.uiSettings;
const onIndexPatternLoadError = (err: Error) =>
core.notifications.toasts.addError(err, {
Expand Down Expand Up @@ -178,30 +175,27 @@ export function getIndexPatternDatasource({
domElement: Element,
props: DatasourceDataPanelProps<IndexPatternPrivateState>
) {
(async () => {
const resolvedSavedObjectsClient = await savedObjectsClient;
render(
<I18nProvider>
<IndexPatternDataPanel
changeIndexPattern={(
id: string,
state: IndexPatternPrivateState,
setState: StateSetter<IndexPatternPrivateState>
) => {
changeIndexPattern({
id,
state,
setState,
savedObjectsClient: resolvedSavedObjectsClient,
onError: onIndexPatternLoadError,
});
}}
{...props}
/>
</I18nProvider>,
domElement
);
})();
render(
<I18nProvider>
<IndexPatternDataPanel
changeIndexPattern={(
id: string,
state: IndexPatternPrivateState,
setState: StateSetter<IndexPatternPrivateState>
) => {
changeIndexPattern({
id,
state,
setState,
savedObjectsClient,
onError: onIndexPatternLoadError,
});
}}
{...props}
/>
</I18nProvider>,
domElement
);
},

getPublicAPI({
Expand All @@ -225,61 +219,55 @@ export function getIndexPatternDatasource({
return null;
},
renderDimensionPanel: (domElement: Element, props: DatasourceDimensionPanelProps) => {
(async () => {
const [coreStart] = await core.getStartServices();
render(
<I18nProvider>
<KibanaContextProvider
services={{
appName: 'lens',
storage,
uiSettings,
data: await data,
savedObjects: coreStart.savedObjects,
docLinks: coreStart.docLinks,
}}
>
<IndexPatternDimensionPanel
state={state}
setState={setState}
uiSettings={uiSettings}
storage={storage}
savedObjectsClient={coreStart.savedObjects.client}
layerId={props.layerId}
http={core.http}
uniqueLabel={columnLabelMap[props.columnId]}
dateRange={dateRange}
{...props}
/>
</KibanaContextProvider>
</I18nProvider>,
domElement
);
})();
render(
<I18nProvider>
<KibanaContextProvider
services={{
appName: 'lens',
storage,
uiSettings,
data,
savedObjects: core.savedObjects,
docLinks: core.docLinks,
}}
>
<IndexPatternDimensionPanel
state={state}
setState={setState}
uiSettings={uiSettings}
storage={storage}
savedObjectsClient={core.savedObjects.client}
layerId={props.layerId}
http={core.http}
uniqueLabel={columnLabelMap[props.columnId]}
dateRange={dateRange}
{...props}
/>
</KibanaContextProvider>
</I18nProvider>,
domElement
);
},

renderLayerPanel: (domElement: Element, props: DatasourceLayerPanelProps) => {
(async () => {
const resolvedSavedObjectsClient = await savedObjectsClient;
render(
<LayerPanel
state={state}
onChangeIndexPattern={indexPatternId => {
changeLayerIndexPattern({
savedObjectsClient: resolvedSavedObjectsClient,
indexPatternId,
setState,
state,
layerId: props.layerId,
onError: onIndexPatternLoadError,
replaceIfPossible: true,
});
}}
{...props}
/>,
domElement
);
})();
render(
<LayerPanel
state={state}
onChangeIndexPattern={indexPatternId => {
changeLayerIndexPattern({
savedObjectsClient,
indexPatternId,
setState,
state,
layerId: props.layerId,
onError: onIndexPatternLoadError,
replaceIfPossible: true,
});
}}
{...props}
/>,
domElement
);
},
};
},
Expand Down
Loading

0 comments on commit b18f96f

Please sign in to comment.