Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
stacey-gammon committed Mar 19, 2020
1 parent cf08850 commit 6d105b5
Show file tree
Hide file tree
Showing 63 changed files with 925 additions and 780 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,27 @@ import { i18n } from '@kbn/i18n';
import {
IContainer,
EmbeddableInput,
EmbeddableFactory,
EmbeddableFactoryDefinition,
} from '../../../../src/plugins/embeddable/public';
import { HelloWorldEmbeddable, HELLO_WORLD_EMBEDDABLE } from './hello_world_embeddable';

export class HelloWorldEmbeddableFactory extends EmbeddableFactory {
public readonly type = HELLO_WORLD_EMBEDDABLE;
export const createHelloWorldEmbeddableFactory = (): EmbeddableFactoryDefinition => {
return {
type: HELLO_WORLD_EMBEDDABLE,

/**
* In our simple example, we let everyone have permissions to edit this. Most
* embeddables should check the UI Capabilities service to be sure of
* the right permissions.
*/
public async isEditable() {
return true;
}

public async create(initialInput: EmbeddableInput, parent?: IContainer) {
return new HelloWorldEmbeddable(initialInput, parent);
}

public getDisplayName() {
return i18n.translate('embeddableExamples.helloworld.displayName', {
defaultMessage: 'hello world',
});
}
}
/**
* In our simple example, we let everyone have permissions to edit this. Most
* embeddables should check the UI Capabilities service to be sure of
* the right permissions.
*/
isEditable: () => Promise.resolve(true),
create: async (initialInput: EmbeddableInput, parent?: IContainer) => {
return new HelloWorldEmbeddable(initialInput, parent);
},
getDisplayName: () => {
return i18n.translate('embeddableExamples.helloworld.displayName', {
defaultMessage: 'hello world',
});
},
};
};
2 changes: 1 addition & 1 deletion examples/embeddable_examples/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { PluginInitializer } from 'kibana/public';
export {
HELLO_WORLD_EMBEDDABLE,
HelloWorldEmbeddable,
HelloWorldEmbeddableFactory,
createHelloWorldEmbeddableFactory,
} from './hello_world';
export { ListContainer, LIST_CONTAINER } from './list_container';
export { TODO_EMBEDDABLE } from './todo';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/

export { ListContainer, LIST_CONTAINER } from './list_container';
export { ListContainerFactory } from './list_container_factory';
export { createListContainerFactory } from './list_container_factory';
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,24 @@
*/

import { i18n } from '@kbn/i18n';
import {
EmbeddableFactory,
ContainerInput,
EmbeddableStart,
} from '../../../../src/plugins/embeddable/public';
import { ContainerInput, EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import { LIST_CONTAINER, ListContainer } from './list_container';

interface StartServices {
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
}

export class ListContainerFactory extends EmbeddableFactory {
public readonly type = LIST_CONTAINER;
public readonly isContainerType = true;

constructor(private getStartServices: () => Promise<StartServices>) {
super();
}

public async isEditable() {
return true;
}

public async create(initialInput: ContainerInput) {
const { getEmbeddableFactory } = await this.getStartServices();
export const createListContainerFactory = (getStartServices: () => Promise<StartServices>) => ({
type: LIST_CONTAINER,
isContainerType: true,
isEditable: async () => true,
create: async (initialInput: ContainerInput) => {
const { getEmbeddableFactory } = await getStartServices();
return new ListContainer(initialInput, getEmbeddableFactory);
}

public getDisplayName() {
},
getDisplayName: () => {
return i18n.translate('embeddableExamples.searchableListContainer.displayName', {
defaultMessage: 'List container',
});
}
}
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,36 @@
*/

import { i18n } from '@kbn/i18n';
import { IContainer, EmbeddableFactory } from '../../../../src/plugins/embeddable/public';
import { IContainer, EmbeddableFactoryDefinition } from '../../../../src/plugins/embeddable/public';
import {
MultiTaskTodoEmbeddable,
MULTI_TASK_TODO_EMBEDDABLE,
MultiTaskTodoInput,
MultiTaskTodoOutput,
} from './multi_task_todo_embeddable';

export class MultiTaskTodoEmbeddableFactory extends EmbeddableFactory<
export const createMultiTaskTodoEmbeddableFactory = (): EmbeddableFactoryDefinition<
MultiTaskTodoInput,
MultiTaskTodoOutput
> {
public readonly type = MULTI_TASK_TODO_EMBEDDABLE;

public async isEditable() {
return true;
}

public async create(initialInput: MultiTaskTodoInput, parent?: IContainer) {
> => ({
type: MULTI_TASK_TODO_EMBEDDABLE,
isEditable: async () => true,
create: async (initialInput: MultiTaskTodoInput, parent?: IContainer) => {
return new MultiTaskTodoEmbeddable(initialInput, parent);
}
},

/**
* Check out todo_embeddable_factory for a better example that asks for data from
* the user. This just returns default data. That's okay too though, if you want to
* start with default data and expose an "edit" action to modify it.
*/
public async getExplicitInput() {
getExplicitInput: async () => {
return { title: 'default title', tasks: ['Im default data'] };
}
},

public getDisplayName() {
getDisplayName: () => {
return i18n.translate('embeddableExamples.multiTaskTodo.displayName', {
defaultMessage: 'Multi-task todo item',
});
}
}
},
});
26 changes: 14 additions & 12 deletions examples/embeddable_examples/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@

import { EmbeddableSetup, EmbeddableStart } from '../../../src/plugins/embeddable/public';
import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public';
import { HelloWorldEmbeddableFactory, HELLO_WORLD_EMBEDDABLE } from './hello_world';
import { TODO_EMBEDDABLE, TodoEmbeddableFactory, TodoInput, TodoOutput } from './todo';
import { MULTI_TASK_TODO_EMBEDDABLE, MultiTaskTodoEmbeddableFactory } from './multi_task_todo';
import { HELLO_WORLD_EMBEDDABLE, createHelloWorldEmbeddableFactory } from './hello_world';
import { TODO_EMBEDDABLE, TodoInput, TodoOutput, createTodoEmbeddableFactory } from './todo';
import {
SEARCHABLE_LIST_CONTAINER,
SearchableListContainerFactory,
} from './searchable_list_container';
import { LIST_CONTAINER, ListContainerFactory } from './list_container';
MULTI_TASK_TODO_EMBEDDABLE,
createMultiTaskTodoEmbeddableFactory,
} from './multi_task_todo';
import { SEARCHABLE_LIST_CONTAINER } from './searchable_list_container';
import { LIST_CONTAINER } from './list_container';
import { createSearchableListContainerFactory } from './searchable_list_container';
import { createListContainerFactory } from './list_container';

interface EmbeddableExamplesSetupDependencies {
embeddable: EmbeddableSetup;
Expand All @@ -45,34 +47,34 @@ export class EmbeddableExamplesPlugin
) {
deps.embeddable.registerEmbeddableFactory(
HELLO_WORLD_EMBEDDABLE,
new HelloWorldEmbeddableFactory()
createHelloWorldEmbeddableFactory()
);

deps.embeddable.registerEmbeddableFactory(
MULTI_TASK_TODO_EMBEDDABLE,
new MultiTaskTodoEmbeddableFactory()
createMultiTaskTodoEmbeddableFactory()
);

// These are registered in the start method because `getEmbeddableFactory `
// is only available in start. We could reconsider this I think and make it
// available in both.
deps.embeddable.registerEmbeddableFactory(
SEARCHABLE_LIST_CONTAINER,
new SearchableListContainerFactory(async () => ({
createSearchableListContainerFactory(async () => ({
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
}))
);

deps.embeddable.registerEmbeddableFactory(
LIST_CONTAINER,
new ListContainerFactory(async () => ({
createListContainerFactory(async () => ({
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
}))
);

deps.embeddable.registerEmbeddableFactory<TodoInput, TodoOutput>(
TODO_EMBEDDABLE,
new TodoEmbeddableFactory(async () => ({
createTodoEmbeddableFactory(async () => ({
openModal: (await core.getStartServices())[0].overlays.openModal,
}))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/

export { SearchableListContainer, SEARCHABLE_LIST_CONTAINER } from './searchable_list_container';
export { SearchableListContainerFactory } from './searchable_list_container_factory';
export { createSearchableListContainerFactory } from './searchable_list_container_factory';
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
*/

import { i18n } from '@kbn/i18n';
import { EmbeddableFactory, EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import {
EmbeddableStart,
EmbeddableFactoryDefinition,
EmbeddableOutput,
} from '../../../../src/plugins/embeddable/public';
import {
SEARCHABLE_LIST_CONTAINER,
SearchableListContainer,
Expand All @@ -29,26 +33,19 @@ interface StartServices {
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
}

export class SearchableListContainerFactory extends EmbeddableFactory {
public readonly type = SEARCHABLE_LIST_CONTAINER;
public readonly isContainerType = true;

constructor(private getStartServices: () => Promise<StartServices>) {
super();
}

public async isEditable() {
return true;
}

public async create(initialInput: SearchableContainerInput) {
const { getEmbeddableFactory } = await this.getStartServices();
export const createSearchableListContainerFactory = (
getStartServices: () => Promise<StartServices>
): EmbeddableFactoryDefinition<SearchableContainerInput, EmbeddableOutput> => ({
isContainerType: true,
type: SEARCHABLE_LIST_CONTAINER,
isEditable: async () => true,
create: async (initialInput: SearchableContainerInput) => {
const { getEmbeddableFactory } = await getStartServices();
return new SearchableListContainer(initialInput, getEmbeddableFactory);
}

public getDisplayName() {
},
getDisplayName: () => {
return i18n.translate('embeddableExamples.searchableListContainer.displayName', {
defaultMessage: 'Searchable list container',
});
}
}
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { OverlayStart } from 'kibana/public';
import { EuiFieldText } from '@elastic/eui';
import { EuiButton } from '@elastic/eui';
import { toMountPoint } from '../../../../src/plugins/kibana_react/public';
import { IContainer, EmbeddableFactory } from '../../../../src/plugins/embeddable/public';
import { IContainer, EmbeddableFactoryDefinition } from '../../../../src/plugins/embeddable/public';
import { TodoEmbeddable, TODO_EMBEDDABLE, TodoInput, TodoOutput } from './todo_embeddable';

function TaskInput({ onSave }: { onSave: (task: string) => void }) {
Expand All @@ -47,33 +47,23 @@ interface StartServices {
openModal: OverlayStart['openModal'];
}

export class TodoEmbeddableFactory extends EmbeddableFactory<
TodoInput,
TodoOutput,
TodoEmbeddable
> {
public readonly type = TODO_EMBEDDABLE;

constructor(private getStartServices: () => Promise<StartServices>) {
super();
}

public async isEditable() {
return true;
}

public async create(initialInput: TodoInput, parent?: IContainer) {
export const createTodoEmbeddableFactory = (
getStartServices: () => Promise<StartServices>
): EmbeddableFactoryDefinition<TodoInput, TodoOutput, TodoEmbeddable> => ({
type: TODO_EMBEDDABLE,
isEditable: async () => true,
create: async (initialInput: TodoInput, parent?: IContainer) => {
return new TodoEmbeddable(initialInput, parent);
}
},

/**
* This function is used when dynamically creating a new embeddable to add to a
* container. Some input may be inherited from the container, but not all. This can be
* used to collect specific embeddable input that the container will not provide, like
* in this case, the task string.
*/
public async getExplicitInput() {
const { openModal } = await this.getStartServices();
getExplicitInput: async () => {
const { openModal } = await getStartServices();
return new Promise<{ task: string }>(resolve => {
const onSave = (task: string) => resolve({ task });
const overlay = openModal(
Expand All @@ -87,11 +77,11 @@ export class TodoEmbeddableFactory extends EmbeddableFactory<
)
);
});
}
},

public getDisplayName() {
getDisplayName: () => {
return i18n.translate('embeddableExamples.todo.displayName', {
defaultMessage: 'Todo item',
});
}
}
},
});
16 changes: 12 additions & 4 deletions examples/embeddable_explorer/public/todo_embeddable_example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ import {
import {
TodoEmbeddable,
TODO_EMBEDDABLE,
TodoEmbeddableFactory,
createTodoEmbeddableFactory,
TodoInput,
} from '../../../examples/embeddable_examples/public/todo';
import { EmbeddableStart, EmbeddableRoot } from '../../../src/plugins/embeddable/public';
import {
EmbeddableStart,
EmbeddableRoot,
EmbeddableOutput,
ErrorEmbeddable,
} from '../../../src/plugins/embeddable/public';

interface Props {
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
Expand All @@ -53,7 +59,7 @@ interface State {
}

export class TodoEmbeddableExample extends React.Component<Props, State> {
private embeddable?: TodoEmbeddable;
private embeddable?: TodoEmbeddable | ErrorEmbeddable;

constructor(props: Props) {
super(props);
Expand All @@ -62,7 +68,9 @@ export class TodoEmbeddableExample extends React.Component<Props, State> {
}

public componentDidMount() {
const factory = this.props.getEmbeddableFactory(TODO_EMBEDDABLE) as TodoEmbeddableFactory;
const factory = this.props.getEmbeddableFactory<TodoInput, EmbeddableOutput, TodoEmbeddable>(
TODO_EMBEDDABLE
);

if (factory === undefined) {
throw new Error('Embeddable factory is undefined!');
Expand Down
Loading

0 comments on commit 6d105b5

Please sign in to comment.