Skip to content

Commit

Permalink
Kibana developer portal
Browse files Browse the repository at this point in the history
  • Loading branch information
stacey-gammon committed May 20, 2020
1 parent 203605e commit 4e758a1
Show file tree
Hide file tree
Showing 31 changed files with 472 additions and 28 deletions.
2 changes: 1 addition & 1 deletion examples/alerting_example/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["triggers_actions_ui", "charts", "data", "alerting", "actions"],
"requiredPlugins": ["triggers_actions_ui", "charts", "data", "alerting", "actions", "developerExamples"],
"optionalPlugins": []
}
Binary file added examples/alerting_example/public/alerting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 22 additions & 2 deletions examples/alerting_example/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@
* under the License.
*/

import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public';
import { Plugin, CoreSetup, AppMountParameters, AppNavLinkStatus } from '../../../src/core/public';
import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerting/public';
import { ChartsPluginStart } from '../../../src/plugins/charts/public';
import { TriggersAndActionsUIPublicPluginSetup } from '../../../x-pack/plugins/triggers_actions_ui/public';
import { DataPublicPluginStart } from '../../../src/plugins/data/public';
import { getAlertType as getAlwaysFiringAlertType } from './alert_types/always_firing';
import { getAlertType as getPeopleInSpaceAlertType } from './alert_types/astros';
import { registerNavigation } from './alert_types';
import { DeveloperExamplesSetup } from '../../developer_examples/public';
import image from './alerting.png';

export type Setup = void;
export type Start = void;

export interface AlertingExamplePublicSetupDeps {
alerting: AlertingSetup;
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
developerExamples: DeveloperExamplesSetup;
}

export interface AlertingExamplePublicStartDeps {
Expand All @@ -44,11 +47,12 @@ export interface AlertingExamplePublicStartDeps {
export class AlertingExamplePlugin implements Plugin<Setup, Start, AlertingExamplePublicSetupDeps> {
public setup(
core: CoreSetup<AlertingExamplePublicStartDeps, Start>,
{ alerting, triggers_actions_ui }: AlertingExamplePublicSetupDeps
{ alerting, triggers_actions_ui, developerExamples }: AlertingExamplePublicSetupDeps
) {
core.application.register({
id: 'AlertingExample',
title: 'Alerting Example',
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
const [coreStart, depsStart] = await core.getStartServices();
const { renderApp } = await import('./application');
Expand All @@ -60,6 +64,22 @@ export class AlertingExamplePlugin implements Plugin<Setup, Start, AlertingExamp
triggers_actions_ui.alertTypeRegistry.register(getPeopleInSpaceAlertType());

registerNavigation(alerting);

developerExamples.register({
appId: 'AlertingExample',
title: 'Alerting',
description: `This alerting example walks you through how to set up a new alert.`,
image,
links: [
{
label: 'README',
href: 'https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting',
iconType: 'logoGithub',
size: 's',
target: '_blank',
},
],
});
}

public start() {}
Expand Down
2 changes: 1 addition & 1 deletion examples/bfetch_explorer/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["bfetch"],
"requiredPlugins": ["bfetch", "developerExamples"],
"optionalPlugins": []
}
Binary file added examples/bfetch_explorer/public/bfetch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 24 additions & 3 deletions examples/bfetch_explorer/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
* under the License.
*/

import { Plugin, CoreSetup } from 'kibana/public';
import { Plugin, CoreSetup, AppNavLinkStatus } from '../../../src/core/public';
import { BfetchPublicSetup, BfetchPublicStart } from '../../../src/plugins/bfetch/public';
import { mount } from './mount';
import { DeveloperExamplesSetup } from '../../developer_examples/public';
import image from './bfetch.png';

export interface ExplorerService {
double: (number: { num: number }) => Promise<{ num: number }>;
}

export interface BfetchExplorerSetupPlugins {
bfetch: BfetchPublicSetup;
developerExamples: DeveloperExamplesSetup;
}

export interface BfetchExplorerStartPlugins {
Expand All @@ -36,9 +39,9 @@ export interface BfetchExplorerStartPlugins {
export class BfetchExplorerPlugin implements Plugin {
public setup(
core: CoreSetup<BfetchExplorerStartPlugins, void>,
plugins: BfetchExplorerSetupPlugins
{ bfetch, developerExamples }: BfetchExplorerSetupPlugins
) {
const double = plugins.bfetch.batchedFunction<{ num: number }, { num: number }>({
const double = bfetch.batchedFunction<{ num: number }, { num: number }>({
url: '/bfetch_explorer/double',
});

Expand All @@ -49,8 +52,26 @@ export class BfetchExplorerPlugin implements Plugin {
core.application.register({
id: 'bfetch-explorer',
title: 'bfetch explorer',
navLinkStatus: AppNavLinkStatus.hidden,
mount: mount(core, explorer),
});

developerExamples.register({
appId: 'bfetch-explorer',
title: 'bfetch',
description:
'bfetch is a service that allows to batch HTTP requests and streams responses back.',
image,
links: [
{
label: 'README',
href: 'https://github.com/elastic/kibana/blob/master/src/plugins/bfetch/README.md',
iconType: 'logoGithub',
size: 's',
target: '_blank',
},
],
});
}

public start() {}
Expand Down
14 changes: 14 additions & 0 deletions examples/developer_examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Developer examples

Owner: Kibana application architecture team

Register your API services, a description, and add links to examples and READMEs. These
will appear in the Developer portal app when Kibana in dev mode, is run via :

```
yarn start --run-examples
```

<img src="./navigation.png" height="400px" />

<img src="./developer_examples.png" height="300px" />
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions examples/developer_examples/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"id": "developerExamples",
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,
"ui": true,
"requiredPlugins": [],
"optionalPlugins": []
}
Binary file added examples/developer_examples/navigation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 112 additions & 0 deletions examples/developer_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, { useState } from 'react';
import ReactDOM from 'react-dom';

import {
EuiText,
EuiPageContent,
EuiCard,
EuiPageContentHeader,
EuiFlexGroup,
EuiFlexItem,
EuiFieldSearch,
EuiListGroup,
EuiHighlight,
} from '@elastic/eui';
import { AppMountParameters } from 'kibana/public';
import { EuiListGroupItemProps } from '@elastic/eui';
import { ExampleDefinition } from './types';

interface Props {
examples: ExampleDefinition[];
navigateToApp: (appId: string) => void;
}

function DeveloperExamples({ examples, navigateToApp }: Props) {
const [search, setSearch] = useState<string>('');

const lcSearch = search.toLowerCase();
const filteredExamples = !lcSearch
? examples
: examples.filter(def => {
if (def.description.toLowerCase().indexOf(lcSearch) >= 0) return true;
if (def.title.toLowerCase().indexOf(lcSearch) >= 0) return true;
return false;
});

return (
<EuiPageContent>
<EuiPageContentHeader>
<EuiText>
<h1>Developer examples</h1>
<p>
The following examples showcase services and APIs that are available to developers.
<EuiFieldSearch
placeholder="Search"
value={search}
onChange={e => setSearch(e.target.value)}
isClearable={true}
aria-label="Search developer examples"
/>
</p>
</EuiText>
</EuiPageContentHeader>
<EuiFlexGroup wrap>
{filteredExamples.map(def => (
<EuiFlexItem style={{ minWidth: 300, maxWidth: 500 }}>
<EuiCard
description={
<EuiHighlight search={search} highlightAll={true}>
{def.description}
</EuiHighlight>
}
title={
<EuiHighlight search={search} highlightAll={true}>
{def.title}
</EuiHighlight>
}
image={def.image}
footer={
<EuiListGroup
size={'s'}
listItems={[
{
label: 'Examples',
onClick: () => navigateToApp(def.appId),
iconType: 'popout',
size: 's',
},
...(def.links ? def.links : []),
]}
/>
}
/>
</EuiFlexItem>
))}
</EuiFlexGroup>
</EuiPageContent>
);
}

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

return () => ReactDOM.unmountComponentAtNode(element);
};
24 changes: 24 additions & 0 deletions examples/developer_examples/public/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 { DeveloperExamplesPlugin } from './plugin';

export const plugin = () => new DeveloperExamplesPlugin();

export { DeveloperExamplesSetup } from './plugin';
67 changes: 67 additions & 0 deletions examples/developer_examples/public/plugin.ts
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 {
CoreSetup,
Plugin,
AppMountParameters,
DEFAULT_APP_CATEGORIES,
} from '../../../src/core/public';

import { ExampleDefinition } from './types';

export interface DeveloperExamplesSetup {
register: (def: ExampleDefinition) => void;
}

export class DeveloperExamplesPlugin implements Plugin<DeveloperExamplesSetup, void> {
private examplesRegistry: ExampleDefinition[] = [];

public setup(core: CoreSetup) {
const examples = this.examplesRegistry;
core.application.register({
id: 'developerExamples',
title: 'Developer examples',
order: -2000,
category: DEFAULT_APP_CATEGORIES.kibana,
async mount(params: AppMountParameters) {
const { renderApp } = await import('./app');
const [coreStart] = await core.getStartServices();
return renderApp(
{
examples,
navigateToApp: (appId: string) => coreStart.application.navigateToApp(appId),
},
params.element
);
},
});

const api: DeveloperExamplesSetup = {
register: def => {
this.examplesRegistry.push(def);
},
};
return api;
}

public start() {}

public stop() {}
}
Loading

0 comments on commit 4e758a1

Please sign in to comment.