Skip to content

Commit dfa083d

Browse files
author
Stacey Gammon
authored
Prep for embed saved object refactor + helper (#62486)
1 parent 0ebfe76 commit dfa083d

File tree

26 files changed

+234
-303
lines changed

26 files changed

+234
-303
lines changed

examples/embeddable_examples/public/list_container/embeddable_list_item.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.

examples/embeddable_examples/public/list_container/list_container.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,25 @@ export class ListContainer extends Container<{}, ContainerInput> {
3131
public readonly type = LIST_CONTAINER;
3232
private node?: HTMLElement;
3333

34-
constructor(
35-
input: ContainerInput,
36-
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']
37-
) {
38-
super(input, { embeddableLoaded: {} }, getEmbeddableFactory);
34+
constructor(input: ContainerInput, private embeddableServices: EmbeddableStart) {
35+
super(input, { embeddableLoaded: {} }, embeddableServices.getEmbeddableFactory);
3936
}
4037

41-
// This container has no input itself.
42-
getInheritedInput(id: string) {
43-
return {};
38+
getInheritedInput() {
39+
return {
40+
viewMode: this.input.viewMode,
41+
};
4442
}
4543

4644
public render(node: HTMLElement) {
4745
this.node = node;
4846
if (this.node) {
4947
ReactDOM.unmountComponentAtNode(this.node);
5048
}
51-
ReactDOM.render(<ListContainerComponent embeddable={this} />, node);
49+
ReactDOM.render(
50+
<ListContainerComponent embeddable={this} embeddableServices={this.embeddableServices} />,
51+
node
52+
);
5253
}
5354

5455
public destroy() {

examples/embeddable_examples/public/list_container/list_container_component.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,35 @@ import {
2424
withEmbeddableSubscription,
2525
ContainerInput,
2626
ContainerOutput,
27+
EmbeddableStart,
2728
} from '../../../../src/plugins/embeddable/public';
28-
import { EmbeddableListItem } from './embeddable_list_item';
2929

3030
interface Props {
3131
embeddable: IContainer;
3232
input: ContainerInput;
3333
output: ContainerOutput;
34+
embeddableServices: EmbeddableStart;
3435
}
3536

36-
function renderList(embeddable: IContainer, panels: ContainerInput['panels']) {
37+
function renderList(
38+
embeddable: IContainer,
39+
panels: ContainerInput['panels'],
40+
embeddableServices: EmbeddableStart
41+
) {
3742
let number = 0;
3843
const list = Object.values(panels).map(panel => {
3944
const child = embeddable.getChild(panel.explicitInput.id);
4045
number++;
4146
return (
4247
<EuiPanel key={number.toString()}>
43-
<EuiFlexGroup>
48+
<EuiFlexGroup gutterSize="none">
4449
<EuiFlexItem grow={false}>
4550
<EuiText>
4651
<h3>{number}</h3>
4752
</EuiText>
4853
</EuiFlexItem>
4954
<EuiFlexItem>
50-
<EmbeddableListItem embeddable={child} />
55+
<embeddableServices.EmbeddablePanel embeddable={child} />
5156
</EuiFlexItem>
5257
</EuiFlexGroup>
5358
</EuiPanel>
@@ -56,12 +61,12 @@ function renderList(embeddable: IContainer, panels: ContainerInput['panels']) {
5661
return list;
5762
}
5863

59-
export function ListContainerComponentInner(props: Props) {
64+
export function ListContainerComponentInner({ embeddable, input, embeddableServices }: Props) {
6065
return (
6166
<div>
62-
<h2 data-test-subj="listContainerTitle">{props.embeddable.getTitle()}</h2>
67+
<h2 data-test-subj="listContainerTitle">{embeddable.getTitle()}</h2>
6368
<EuiSpacer size="l" />
64-
{renderList(props.embeddable, props.input.panels)}
69+
{renderList(embeddable, input.panels, embeddableServices)}
6570
</div>
6671
);
6772
}
@@ -71,4 +76,9 @@ export function ListContainerComponentInner(props: Props) {
7176
// anything on input or output state changes. If you don't want that to happen (for example
7277
// if you expect something on input or output state to change frequently that your react
7378
// component does not care about, then you should probably hook this up manually).
74-
export const ListContainerComponent = withEmbeddableSubscription(ListContainerComponentInner);
79+
export const ListContainerComponent = withEmbeddableSubscription<
80+
ContainerInput,
81+
ContainerOutput,
82+
IContainer,
83+
{ embeddableServices: EmbeddableStart }
84+
>(ListContainerComponentInner);

examples/embeddable_examples/public/list_container/list_container_factory.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import { LIST_CONTAINER, ListContainer } from './list_container';
2727

2828
interface StartServices {
29-
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
29+
embeddableServices: EmbeddableStart;
3030
}
3131

3232
export class ListContainerFactory implements EmbeddableFactoryDefinition {
@@ -40,8 +40,8 @@ export class ListContainerFactory implements EmbeddableFactoryDefinition {
4040
}
4141

4242
public create = async (initialInput: ContainerInput) => {
43-
const { getEmbeddableFactory } = await this.getStartServices();
44-
return new ListContainer(initialInput, getEmbeddableFactory);
43+
const { embeddableServices } = await this.getStartServices();
44+
return new ListContainer(initialInput, embeddableServices);
4545
};
4646

4747
public getDisplayName() {

examples/embeddable_examples/public/multi_task_todo/multi_task_todo_component.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function wrapSearchTerms(task: string, search?: string) {
5454
);
5555
}
5656

57-
function renderTasks(tasks: MultiTaskTodoOutput['tasks'], search?: string) {
57+
function renderTasks(tasks: MultiTaskTodoInput['tasks'], search?: string) {
5858
return tasks.map(task => (
5959
<EuiListGroupItem
6060
key={task}
@@ -65,16 +65,15 @@ function renderTasks(tasks: MultiTaskTodoOutput['tasks'], search?: string) {
6565
}
6666

6767
export function MultiTaskTodoEmbeddableComponentInner({
68-
input: { title, icon, search },
69-
output: { tasks },
68+
input: { title, icon, search, tasks },
7069
}: Props) {
7170
return (
72-
<EuiFlexGroup>
71+
<EuiFlexGroup gutterSize="none">
7372
<EuiFlexItem grow={false}>
7473
{icon ? <EuiIcon type={icon} size="l" /> : <EuiAvatar name={title} size="l" />}
7574
</EuiFlexItem>
7675
<EuiFlexItem>
77-
<EuiFlexGrid columns={1}>
76+
<EuiFlexGrid columns={1} gutterSize="none">
7877
<EuiFlexItem>
7978
<EuiText data-test-subj="multiTaskTodoTitle">
8079
<h3>{wrapSearchTerms(title, search)}</h3>
@@ -89,6 +88,8 @@ export function MultiTaskTodoEmbeddableComponentInner({
8988
);
9089
}
9190

92-
export const MultiTaskTodoEmbeddableComponent = withEmbeddableSubscription(
93-
MultiTaskTodoEmbeddableComponentInner
94-
);
91+
export const MultiTaskTodoEmbeddableComponent = withEmbeddableSubscription<
92+
MultiTaskTodoInput,
93+
MultiTaskTodoOutput,
94+
MultiTaskTodoEmbeddable
95+
>(MultiTaskTodoEmbeddableComponentInner);

examples/embeddable_examples/public/multi_task_todo/multi_task_todo_embeddable.tsx

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,27 @@ export interface MultiTaskTodoInput extends EmbeddableInput {
3636
title: string;
3737
}
3838

39-
// This embeddable has output! It's the tasks list that is filtered.
40-
// Output state is something only the embeddable itself can update. It
41-
// can be something completely internal, or it can be state that is
39+
// This embeddable has output! Output state is something only the embeddable itself
40+
// can update. It can be something completely internal, or it can be state that is
4241
// derived from input state and updates when input does.
4342
export interface MultiTaskTodoOutput extends EmbeddableOutput {
44-
tasks: string[];
43+
hasMatch: boolean;
4544
}
4645

47-
function getFilteredTasks(tasks: string[], search?: string) {
48-
const filteredTasks: string[] = [];
49-
if (search === undefined) return tasks;
46+
function getHasMatch(tasks: string[], title?: string, search?: string) {
47+
if (search === undefined || search === '') return false;
5048

51-
tasks.forEach(task => {
52-
if (task.match(search)) {
53-
filteredTasks.push(task);
54-
}
55-
});
49+
if (title && title.match(search)) return true;
50+
51+
const match = tasks.find(task => task.match(search));
52+
if (match) return true;
5653

57-
return filteredTasks;
54+
return false;
5855
}
5956

6057
function getOutput(input: MultiTaskTodoInput) {
61-
const tasks = getFilteredTasks(input.tasks, input.search);
62-
return { tasks, hasMatch: tasks.length > 0 || (input.search && input.title.match(input.search)) };
58+
const hasMatch = getHasMatch(input.tasks, input.title, input.search);
59+
return { hasMatch };
6360
}
6461

6562
export class MultiTaskTodoEmbeddable extends Embeddable<MultiTaskTodoInput, MultiTaskTodoOutput> {

examples/embeddable_examples/public/plugin.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,17 @@ export class EmbeddableExamplesPlugin
5353
new MultiTaskTodoEmbeddableFactory()
5454
);
5555

56-
// These are registered in the start method because `getEmbeddableFactory `
57-
// is only available in start. We could reconsider this I think and make it
58-
// available in both.
5956
deps.embeddable.registerEmbeddableFactory(
6057
SEARCHABLE_LIST_CONTAINER,
6158
new SearchableListContainerFactory(async () => ({
62-
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
59+
embeddableServices: (await core.getStartServices())[1].embeddable,
6360
}))
6461
);
6562

6663
deps.embeddable.registerEmbeddableFactory(
6764
LIST_CONTAINER,
6865
new ListContainerFactory(async () => ({
69-
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
66+
embeddableServices: (await core.getStartServices())[1].embeddable,
7067
}))
7168
);
7269

examples/embeddable_examples/public/searchable_list_container/searchable_list_container.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,8 @@ export class SearchableListContainer extends Container<ChildInput, SearchableCon
4040
public readonly type = SEARCHABLE_LIST_CONTAINER;
4141
private node?: HTMLElement;
4242

43-
constructor(
44-
input: SearchableContainerInput,
45-
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']
46-
) {
47-
super(input, { embeddableLoaded: {} }, getEmbeddableFactory);
43+
constructor(input: SearchableContainerInput, private embeddableServices: EmbeddableStart) {
44+
super(input, { embeddableLoaded: {} }, embeddableServices.getEmbeddableFactory);
4845
}
4946

5047
// TODO: add a more advanced example here where inherited child input is derived from container
@@ -53,6 +50,7 @@ export class SearchableListContainer extends Container<ChildInput, SearchableCon
5350
return {
5451
id,
5552
search: this.getInput().search,
53+
viewMode: this.input.viewMode,
5654
};
5755
}
5856

@@ -61,7 +59,13 @@ export class SearchableListContainer extends Container<ChildInput, SearchableCon
6159
ReactDOM.unmountComponentAtNode(this.node);
6260
}
6361
this.node = node;
64-
ReactDOM.render(<SearchableListContainerComponent embeddable={this} />, node);
62+
ReactDOM.render(
63+
<SearchableListContainerComponent
64+
embeddable={this}
65+
embeddableServices={this.embeddableServices}
66+
/>,
67+
node
68+
);
6569
}
6670

6771
public destroy() {

0 commit comments

Comments
 (0)