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 all 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
1 change: 1 addition & 0 deletions examples/dashboard_embeddable_examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Example of using dashboard container embeddable outside of dashboard app
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", "developerExamples"],
"optionalPlugins": []
}
112 changes: 112 additions & 0 deletions examples/dashboard_embeddable_examples/public/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* 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 { 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;
DashboardContainerByValueRenderer: DashboardStart['DashboardContainerByValueRenderer'];
}

const DashboardEmbeddableExplorerApp = ({ basename, DashboardContainerByValueRenderer }: Props) => {
const pages: PageDef[] = [
{
title: 'By value dashboard embeddable',
id: 'dashboardEmbeddableByValue',
component: (
<DashboardEmbeddableByValue
DashboardContainerByValueRenderer={DashboardContainerByValueRenderer}
/>
),
},
{
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);
};
120 changes: 120 additions & 0 deletions examples/dashboard_embeddable_examples/public/by_value/embeddable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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';
import { TODO_EMBEDDABLE } from '../../../embeddable_examples/public/todo';
import { TODO_REF_EMBEDDABLE } from '../../../embeddable_examples/public/todo/todo_ref_embeddable';

const initialInput: DashboardContainerInput = {
viewMode: ViewMode.VIEW,
panels: {
'1': {
gridData: {
w: 10,
h: 10,
x: 0,
y: 0,
i: '1',
},
type: HELLO_WORLD_EMBEDDABLE,
explicitInput: {
id: '1',
},
},
'2': {
gridData: {
w: 10,
h: 10,
x: 10,
y: 0,
i: '2',
},
type: HELLO_WORLD_EMBEDDABLE,
explicitInput: {
id: '2',
},
},
'3': {
gridData: {
w: 10,
h: 10,
x: 0,
y: 10,
i: '3',
},
type: TODO_EMBEDDABLE,
explicitInput: {
id: '3',
title: 'Clean up',
task: 'Clean up the code',
icon: 'trash',
},
},
'4': {
gridData: {
w: 10,
h: 10,
x: 10,
y: 10,
i: '4',
},
type: TODO_REF_EMBEDDABLE,
explicitInput: {
id: '4',
savedObjectId: 'sample-todo-saved-object',
},
},
},
isFullScreenMode: false,
filters: [],
useMargins: false,
id: 'random-id',
timeRange: {
to: 'now',
from: 'now-1d',
},
title: 'test',
query: {
query: '',
language: 'lucene',
},
refreshConfig: {
pause: true,
value: 15,
},
};

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

return (
<>
<InputEditor input={input} onSubmit={setInput} />
<DashboardContainerByValueRenderer input={input} onInputUpdated={setInput} />
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 } from '@elastic/eui';
import { JsonEditor } from '../../../../src/plugins/es_ui_shared/public';

export const InputEditor = <T,>(props: { input: T; onSubmit: (value: T) => void }) => {
const input = JSON.stringify(props.input, null, 4);
const [value, setValue] = React.useState(input);
const isValid = (() => {
try {
JSON.parse(value);
return true;
} catch (e) {
return false;
}
})();
React.useEffect(() => {
setValue(input);
}, [input]);
return (
<>
<JsonEditor
value={value}
onUpdate={(v) => setValue(v.data.raw)}
euiCodeEditorProps={{
'data-test-subj': 'dashboardEmbeddableByValueInputEditor',
}}
/>
<EuiButton
onClick={() => props.onSubmit(JSON.parse(value))}
disabled={!isValid}
data-test-subj={'dashboardEmbeddableByValueInputSubmit'}
>
Update Input
</EuiButton>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@
* under the License.
*/

export { App } from './app';
import { DashboardEmbeddableExamples } from './plugin';

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

interface SetupDeps {
developerExamples: DeveloperExamplesSetup;
}

interface StartDeps {
dashboard: DashboardStart;
embeddableExamples: EmbeddableExamplesStart;
}

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

developerExamples.register({
appId: 'dashboardEmbeddableExamples',
title: 'Dashboard Container',
description: `Showcase different ways how to embed dashboard container into your app`,
});
}

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": []
}
Loading