Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Add embeddable via saved object example
  • Loading branch information
stacey-gammon committed Mar 31, 2020
1 parent 810cbd2 commit fcd2ccf
Show file tree
Hide file tree
Showing 59 changed files with 1,681 additions and 180 deletions.
20 changes: 20 additions & 0 deletions examples/embeddable_examples/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export { TodoSavedObjectAttributes } from './types';
26 changes: 26 additions & 0 deletions examples/embeddable_examples/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { SavedObjectAttributes } from 'kibana/public';

export interface TodoSavedObjectAttributes extends SavedObjectAttributes {
task: string;
icon?: string;
title?: string;
}
4 changes: 2 additions & 2 deletions examples/embeddable_examples/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["embeddable_examples"],
"server": false,
"server": true,
"ui": true,
"requiredPlugins": ["embeddable"],
"requiredPlugins": ["embeddable", "uiActions", "inspector"],
"optionalPlugins": []
}
36 changes: 36 additions & 0 deletions examples/embeddable_examples/public/create_sample_data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { SavedObjectsClientContract } from 'kibana/public';
import { TodoSavedObjectAttributes } from '../common';

export async function createSampleData(client: SavedObjectsClientContract, overwrite = true) {
await client.create<TodoSavedObjectAttributes>(
'todo',
{
task: 'Take the garbage out',
title: 'Garbage',
icon: 'trash',
},
{
id: 'sample-todo-saved-object',
overwrite,
}
);
}
22 changes: 9 additions & 13 deletions examples/embeddable_examples/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* under the License.
*/

import { PluginInitializer } from 'kibana/public';
export {
HELLO_WORLD_EMBEDDABLE,
HelloWorldEmbeddable,
Expand All @@ -26,18 +25,15 @@ export {
export { ListContainer, LIST_CONTAINER } from './list_container';
export { TODO_EMBEDDABLE } from './todo';

import {
EmbeddableExamplesPlugin,
EmbeddableExamplesSetupDependencies,
EmbeddableExamplesStartDependencies,
} from './plugin';
import { EmbeddableExamplesPlugin } from './plugin';

export { SearchableListContainer, SEARCHABLE_LIST_CONTAINER } from './searchable_list_container';
export { MULTI_TASK_TODO_EMBEDDABLE } from './multi_task_todo';
export {
TODO_SO_EMBEDDABLE,
TodoSoEmbeddable,
TodoSoEmbeddableInput,
TodoSoEmbeddableOutput,
} from './todo_saved_object';

export const plugin: PluginInitializer<
void,
void,
EmbeddableExamplesSetupDependencies,
EmbeddableExamplesStartDependencies
> = () => new EmbeddableExamplesPlugin();
export { MULTI_TASK_TODO_EMBEDDABLE } from './multi_task_todo';
export const plugin = () => new EmbeddableExamplesPlugin();
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,27 @@
*/

import React from 'react';
import { EuiPanel, EuiLoadingSpinner, EuiFlexItem } from '@elastic/eui';
import { IEmbeddable } from '../../../../src/plugins/embeddable/public';
import { EuiLoadingSpinner, EuiFlexItem } from '@elastic/eui';
import { CoreStart, IUiSettingsClient, SavedObjectsStart } from 'kibana/public';
import { UiActionsStart } from '../../../../src/plugins/ui_actions/public';
import { Start as InspectorStart } from '../../../../src/plugins/inspector/public';
import { getSavedObjectFinder } from '../../../../src/plugins/saved_objects/public';
import {
IEmbeddable,
EmbeddableStart,
EmbeddablePanel,
} from '../../../../src/plugins/embeddable/public';

interface Props {
embeddable: IEmbeddable;
uiActionsApi: UiActionsStart;
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: CoreStart['overlays'];
notifications: CoreStart['notifications'];
inspector: InspectorStart;
savedObject: SavedObjectsStart;
uiSettingsClient: IUiSettingsClient;
}

export class EmbeddableListItem extends React.Component<Props> {
Expand All @@ -49,15 +65,33 @@ export class EmbeddableListItem extends React.Component<Props> {
}

public render() {
const {
embeddable,
uiActionsApi,
getAllEmbeddableFactories,
getEmbeddableFactory,
savedObject,
uiSettingsClient,
notifications,
inspector,
overlays,
} = this.props;
return (
<EuiFlexItem>
<EuiPanel>
{this.props.embeddable ? (
<div ref={this.embeddableRoot} />
) : (
<EuiLoadingSpinner size="s" />
)}
</EuiPanel>
{embeddable ? (
<EmbeddablePanel
embeddable={embeddable}
getActions={uiActionsApi.getTriggerCompatibleActions}
getEmbeddableFactory={getEmbeddableFactory}
getAllEmbeddableFactories={getAllEmbeddableFactories}
overlays={overlays}
notifications={notifications}
inspector={inspector}
SavedObjectFinder={getSavedObjectFinder(savedObject, uiSettingsClient)}
/>
) : (
<EuiLoadingSpinner size="s" />
)}
</EuiFlexItem>
);
}
Expand Down
4 changes: 2 additions & 2 deletions examples/embeddable_examples/public/list_container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
* under the License.
*/

export { ListContainer, LIST_CONTAINER } from './list_container';
export { ListContainerFactory } from './list_container_factory';
export * from './list_container';
export * from './list_container_factory';
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,18 @@
*/
import React from 'react';
import ReactDOM from 'react-dom';
import {
Container,
ContainerInput,
EmbeddableStart,
} from '../../../../src/plugins/embeddable/public';
import { Container, ContainerInput } from '../../../../src/plugins/embeddable/public';
import { ListContainerComponent } from './list_container_component';
import { StartServices } from './list_container_factory';

export const LIST_CONTAINER = 'LIST_CONTAINER';

export class ListContainer extends Container<{}, ContainerInput> {
public readonly type = LIST_CONTAINER;
private node?: HTMLElement;

constructor(
input: ContainerInput,
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']
) {
super(input, { embeddableLoaded: {} }, getEmbeddableFactory);
constructor(input: ContainerInput, private services: StartServices) {
super(input, { embeddableLoaded: {} }, services.getEmbeddableFactory);
}

// This container has no input itself.
Expand All @@ -48,7 +42,7 @@ export class ListContainer extends Container<{}, ContainerInput> {
if (this.node) {
ReactDOM.unmountComponentAtNode(this.node);
}
ReactDOM.render(<ListContainerComponent embeddable={this} />, node);
ReactDOM.render(<ListContainerComponent embeddable={this} services={this.services} />, node);
}

public destroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,34 @@ import {
ContainerOutput,
} from '../../../../src/plugins/embeddable/public';
import { EmbeddableListItem } from './embeddable_list_item';
import { StartServices } from './list_container_factory';

interface Props {
embeddable: IContainer;
input: ContainerInput;
output: ContainerOutput;
services: StartServices;
}

function renderList(embeddable: IContainer, panels: ContainerInput['panels']) {
function renderList(
embeddable: IContainer,
panels: ContainerInput['panels'],
services: StartServices
) {
let number = 0;
const list = Object.values(panels).map(panel => {
const child = embeddable.getChild(panel.explicitInput.id);
number++;
return (
<EuiPanel key={number.toString()}>
<EuiFlexGroup>
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<EuiText>
<h3>{number}</h3>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EmbeddableListItem embeddable={child} />
<EmbeddableListItem embeddable={child} {...services} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
Expand All @@ -61,7 +67,7 @@ export function ListContainerComponentInner(props: Props) {
<div>
<h2 data-test-subj="listContainerTitle">{props.embeddable.getTitle()}</h2>
<EuiSpacer size="l" />
{renderList(props.embeddable, props.input.panels)}
{renderList(props.embeddable, props.input.panels, props.services)}
</div>
);
}
Expand All @@ -71,4 +77,9 @@ export function ListContainerComponentInner(props: Props) {
// anything on input or output state changes. If you don't want that to happen (for example
// if you expect something on input or output state to change frequently that your react
// component does not care about, then you should probably hook this up manually).
export const ListContainerComponent = withEmbeddableSubscription(ListContainerComponentInner);
export const ListContainerComponent = withEmbeddableSubscription<
ContainerInput,
ContainerOutput,
IContainer,
{ services: StartServices }
>(ListContainerComponentInner);
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,25 @@
*/

import { i18n } from '@kbn/i18n';
import { UiActionsStart } from 'src/plugins/ui_actions/public';
import { OverlayStart, CoreStart, SavedObjectsStart, IUiSettingsClient } from 'kibana/public';
import { Start as InspectorStart } from 'src/plugins/inspector/public';
import {
EmbeddableFactory,
ContainerInput,
EmbeddableStart,
} from '../../../../src/plugins/embeddable/public';
import { LIST_CONTAINER, ListContainer } from './list_container';

interface StartServices {
export interface StartServices {
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
uiActionsApi: UiActionsStart;
overlays: OverlayStart;
notifications: CoreStart['notifications'];
inspector: InspectorStart;
savedObject: SavedObjectsStart;
uiSettingsClient: IUiSettingsClient;
}

export class ListContainerFactory extends EmbeddableFactory {
Expand All @@ -42,8 +52,8 @@ export class ListContainerFactory extends EmbeddableFactory {
}

public async create(initialInput: ContainerInput) {
const { getEmbeddableFactory } = await this.getStartServices();
return new ListContainer(initialInput, getEmbeddableFactory);
const services = await this.getStartServices();
return new ListContainer(initialInput, services);
}

public getDisplayName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ export function MultiTaskTodoEmbeddableComponentInner({
);
}

export const MultiTaskTodoEmbeddableComponent = withEmbeddableSubscription(
MultiTaskTodoEmbeddableComponentInner
);
export const MultiTaskTodoEmbeddableComponent = withEmbeddableSubscription<
MultiTaskTodoInput,
MultiTaskTodoOutput,
MultiTaskTodoEmbeddable
>(MultiTaskTodoEmbeddableComponentInner);
Loading

0 comments on commit fcd2ccf

Please sign in to comment.