Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed dashboard by value example & some embeddable clean up #67783

Merged
merged 30 commits into from
Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
381b3ae
draft dashboard embeddable example
Dosant May 28, 2020
7b9bdf9
fix lint
Dosant May 28, 2020
435d52c
comment
Dosant May 28, 2020
3d0cda9
extend the range
Dosant May 28, 2020
a79e0c5
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant May 29, 2020
cae54bb
wip
Dosant May 29, 2020
9f2c8e8
fix
Dosant May 29, 2020
1b14c9a
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 2, 2020
fd989a8
wip
Dosant Jun 2, 2020
f4cca68
fix
Dosant Jun 2, 2020
fc06e07
simplify
Dosant Jun 3, 2020
3035778
remove old test. add test for example
Dosant Jun 3, 2020
f1083a7
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 4, 2020
71d7fb3
add simple unit test
Dosant Jun 4, 2020
a874182
update renovate
Dosant Jun 4, 2020
b7b507c
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 8, 2020
5c7b2c5
review
Dosant Jun 8, 2020
117a277
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 8, 2020
e3ddfa7
fix test subject
Dosant Jun 8, 2020
34a85b9
fix ts
Dosant Jun 8, 2020
eef8b8c
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 8, 2020
23e1ff4
fixes
Dosant Jun 8, 2020
19c1515
add readme
Dosant Jun 8, 2020
0b7305c
Merge branch 'master' of github.com:elastic/kibana into dev/embed-das…
Dosant Jun 9, 2020
6c94e47
make isEmbeddedExternally optional
Dosant Jun 9, 2020
49ab828
better defaults for example
Dosant Jun 9, 2020
516da77
merge
Dosant Jun 11, 2020
76f8e21
remove redundant prop
Dosant Jun 11, 2020
54645c8
ensure sample data is loaded
Dosant Jun 11, 2020
881526a
Merge branch 'master' into dev/embed-dashboard-by-value-example
elasticmachine Jun 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/dashboard_embeddable_examples/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"id": "dashboardEmbeddableExamples",
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,
"ui": true,
"requiredPlugins": ["embeddable", "embeddableExamples", "dashboard"],
"optionalPlugins": []
}
117 changes: 117 additions & 0 deletions examples/dashboard_embeddable_examples/public/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* 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 React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, RouteComponentProps, withRouter } from 'react-router-dom';

import {
EuiPage,
EuiPageContent,
EuiPageContentBody,
EuiPageSideBar,
EuiSideNav,
} from '@elastic/eui';
import 'brace/mode/json';
import { EmbeddableStart } from '../../../src/plugins/embeddable/public';
import { AppMountParameters } from '../../../src/core/public';
import { DashboardEmbeddableByValue } from './by_value/embeddable';
import { DashboardStart } from '../../../src/plugins/dashboard/public';

interface PageDef {
title: string;
id: string;
component: React.ReactNode;
}

type NavProps = RouteComponentProps & {
pages: PageDef[];
};

const Nav = withRouter(({ history, pages }: NavProps) => {
const navItems = pages.map((page) => ({
id: page.id,
name: page.title,
onClick: () => history.push(`/${page.id}`),
'data-test-subj': page.id,
}));

return (
<EuiSideNav
items={[
{
name: 'Embeddable explorer',
id: 'home',
items: [...navItems],
},
]}
/>
);
});

interface Props {
basename: string;
DashboardEmbeddableByValueRenderer: DashboardStart['DashboardEmbeddableByValueRenderer'];
embeddableApi: EmbeddableStart;
}

const DashboardEmbeddableExplorerApp = ({
basename,
DashboardEmbeddableByValueRenderer,
}: Props) => {
const pages: PageDef[] = [
{
title: 'By value dashboard embeddable',
id: 'dashboardEmbeddableByValue',
component: (
<DashboardEmbeddableByValue
DashboardEmbeddableByValueRenderer={DashboardEmbeddableByValueRenderer}
/>
),
},
{
title: 'By ref dashboard embeddable',
id: 'dashboardEmbeddableByRef',
component: <div>TODO: Not implemented, but coming soon...</div>,
},
];

const routes = pages.map((page, i) => (
<Route key={i} path={`/${page.id}`} render={(props) => page.component} />
));

return (
<Router basename={basename}>
<EuiPage>
<EuiPageSideBar>
<Nav pages={pages} />
</EuiPageSideBar>
<EuiPageContent>
<EuiPageContentBody>{routes}</EuiPageContentBody>
</EuiPageContent>
</EuiPage>
</Router>
);
};

export const renderApp = (props: Props, element: AppMountParameters['element']) => {
ReactDOM.render(<DashboardEmbeddableExplorerApp {...props} />, element);

return () => ReactDOM.unmountComponentAtNode(element);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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 React, { useState } from 'react';
import { ViewMode } from '../../../../src/plugins/embeddable/public';
import { DashboardContainerInput, DashboardStart } from '../../../../src/plugins/dashboard/public';
import { HELLO_WORLD_EMBEDDABLE } from '../../../embeddable_examples/public/hello_world';
import { InputEditor } from './input_editor';

const initialInput: DashboardContainerInput = {
id: 'random-id',
// TODO: do we need all of this props? Looks like we can make those optional
viewMode: ViewMode.VIEW,
filters: [],
timeRange: { to: 'now', from: 'now-1d' },
useMargins: false,
title: 'test',
query: { query: '', language: 'lucene' },
isFullScreenMode: false,
refreshConfig: { pause: true, value: 15 },
panels: {
'1': {
gridData: {
w: 10,
h: 10,
x: 0,
y: 0,
i: '1',
},
type: HELLO_WORLD_EMBEDDABLE,
explicitInput: {
id: '1',
},
},
},
};

export const DashboardEmbeddableByValue = ({
DashboardEmbeddableByValueRenderer,
}: {
DashboardEmbeddableByValueRenderer: DashboardStart['DashboardEmbeddableByValueRenderer'];
}) => {
const [input, setInput] = useState(initialInput);

return (
<>
<InputEditor initialValue={initialInput} onSubmit={setInput} />
<DashboardEmbeddableByValueRenderer input={input} />
Dosant marked this conversation as resolved.
Show resolved Hide resolved
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 React from 'react';
import { EuiButton, EuiCodeEditor } from '@elastic/eui';

// @ts-ignore
const TextMode = window.ace.acequire('ace/mode/json').Mode;
export const InputEditor = <T,>(props: { initialValue: T; onSubmit: (value: T) => void }) => {
const [value, setValue] = React.useState(JSON.stringify(props.initialValue, null, 4));
const isValid = (() => {
try {
JSON.parse(value);
return true;
} catch (e) {
return false;
}
})();
return (
<>
<EuiCodeEditor
mode={new TextMode()}
Dosant marked this conversation as resolved.
Show resolved Hide resolved
theme="github"
width="100%"
value={value}
onChange={setValue}
setOptions={{ fontSize: '14px' }}
/>
<EuiButton onClick={() => props.onSubmit(JSON.parse(value))} disabled={!isValid}>
Update Input
</EuiButton>
</>
);
};
22 changes: 22 additions & 0 deletions examples/dashboard_embeddable_examples/public/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { DashboardEmbeddableExamples } from './plugin';

export const plugin = () => new DashboardEmbeddableExamples();
49 changes: 49 additions & 0 deletions examples/dashboard_embeddable_examples/public/plugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 { AppMountParameters, CoreSetup, Plugin } from 'kibana/public';
import { DashboardStart } from '../../../src/plugins/dashboard/public';

interface StartDeps {
dashboard: DashboardStart;
}

export class DashboardEmbeddableExamples implements Plugin<void, void, {}, StartDeps> {
public setup(core: CoreSetup<StartDeps>) {
core.application.register({
id: 'dashboardEmbeddableExamples',
title: 'Dashboard embeddable examples',
async mount(params: AppMountParameters) {
const [, depsStart] = await core.getStartServices();
const { renderApp } = await import('./app');
return renderApp(
{
basename: params.appBasePath,
DashboardEmbeddableByValueRenderer:
depsStart.dashboard.DashboardEmbeddableByValueRenderer,
},
params.element
);
},
});
}

public start() {}
public stop() {}
}
15 changes: 15 additions & 0 deletions examples/dashboard_embeddable_examples/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./target",
"skipLibCheck": true
},
"include": [
"index.ts",
"public/**/*.ts",
"public/**/*.tsx",
"server/**/*.ts",
"../../typings/**/*",
],
"exclude": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export class ListContainer extends Container<{}, ContainerInput> {
}

public render(node: HTMLElement) {
this.node = node;
if (this.node) {
ReactDOM.unmountComponentAtNode(this.node);
}
this.node = node;
Dosant marked this conversation as resolved.
Show resolved Hide resolved
ReactDOM.render(
<ListContainerComponent embeddable={this} embeddableServices={this.embeddableServices} />,
node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
*/

import { i18n } from '@kbn/i18n';
import { IContainer, EmbeddableFactoryDefinition } from '../../../../src/plugins/embeddable/public';
import {
IContainer,
EmbeddableFactoryDefinition,
BindEmbeddableFactoryDefinitionOutputType,
} from '../../../../src/plugins/embeddable/public';
import {
MultiTaskTodoEmbeddable,
MULTI_TASK_TODO_EMBEDDABLE,
Expand All @@ -27,6 +31,7 @@ import {
} from './multi_task_todo_embeddable';

export class MultiTaskTodoEmbeddableFactory
extends BindEmbeddableFactoryDefinitionOutputType<MultiTaskTodoOutput>
implements EmbeddableFactoryDefinition<MultiTaskTodoInput, MultiTaskTodoOutput> {
public readonly type = MULTI_TASK_TODO_EMBEDDABLE;

Expand Down
Loading